1
0
Fork 0

small code refactoring

This commit is contained in:
Jan Steemann 2016-02-15 17:02:36 +01:00
parent 7ff95c4ec4
commit 242481a501
7 changed files with 236 additions and 195 deletions

View File

@ -32,6 +32,7 @@
#include <unordered_set>
#include "velocypack/velocypack-common.h"
#include "velocypack/Exception.h"
#include "velocypack/Options.h"
#include "velocypack/Slice.h"
@ -50,6 +51,15 @@ struct TopLevelAttributeExcludeHandler final : AttributeExcludeHandler {
std::unordered_set<std::string> attributes;
};
static inline Slice buildNullValue(char* dst, size_t length) {
if (length < 1) {
throw Exception(Exception::InternalError, "supplied buffer is too small");
}
*dst = 0x18;
return Slice(dst);
}
} // namespace arangodb::velocypack
} // namespace arangodb

View File

@ -34,7 +34,9 @@
#include "VocBase/Traverser.h"
#include "VocBase/server.h"
#include <velocypack/Helpers.h>
#include <velocypack/Iterator.h>
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::basics;
@ -123,6 +125,59 @@ std::map<std::string, std::string> getForwardableRequestHeaders(
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check if a list of attributes have the same values in two vpack
/// documents
////////////////////////////////////////////////////////////////////////////////
bool shardKeysChanged(std::string const& dbname, std::string const& collname,
VPackSlice const& oldValue, VPackSlice const& newValue,
bool isPatch) {
if (!oldValue.isObject() || !newValue.isObject()) {
// expecting two objects. everything else is an error
return true;
}
ClusterInfo* ci = ClusterInfo::instance();
std::shared_ptr<CollectionInfo> c = ci->getCollection(dbname, collname);
std::vector<std::string> const& shardKeys = c->shardKeys();
for (size_t i = 0; i < shardKeys.size(); ++i) {
if (shardKeys[i] == TRI_VOC_ATTRIBUTE_KEY) {
continue;
}
VPackSlice n = newValue.get(shardKeys[i]);
if (n.isNone() && isPatch) {
// attribute not set in patch document. this means no update
continue;
}
// a temporary buffer to hold a null value
char buffer[1];
VPackSlice nullValue = arangodb::velocypack::buildNullValue(&buffer[0], sizeof(buffer));
VPackSlice o = oldValue.get(shardKeys[i]);
if (o.isNone()) {
// if attribute is undefined, use "null" instead
o = nullValue;
}
if (n.isNone()) {
// if attribute is undefined, use "null" instead
n = nullValue;
}
if (! n.equals(o)) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check if a list of attributes have the same values in two JSON
/// documents

View File

@ -33,6 +33,9 @@
#include "VocBase/update-policy.h"
#include "VocBase/voc-types.h"
#include <velocypack/Slice.h>
#include <velocypack/velocypack-aliases.h>
struct TRI_json_t;
namespace arangodb {
@ -68,6 +71,15 @@ bool shardKeysChanged(std::string const& dbname, std::string const& collname,
struct TRI_json_t const* oldJson,
struct TRI_json_t const* newJson, bool isPatch);
////////////////////////////////////////////////////////////////////////////////
/// @brief check if a list of attributes have the same values in two vpack
/// documents
////////////////////////////////////////////////////////////////////////////////
bool shardKeysChanged(std::string const& dbname, std::string const& collname,
VPackSlice const& oldValue, VPackSlice const& newValue,
bool isPatch);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns users
////////////////////////////////////////////////////////////////////////////////

View File

@ -79,7 +79,7 @@ class SingleCollectionWriteTransaction : public SingleCollectionTransaction {
/// @brief end the transaction
//////////////////////////////////////////////////////////////////////////////
virtual ~SingleCollectionWriteTransaction() {}
~SingleCollectionWriteTransaction() {}
public:
//////////////////////////////////////////////////////////////////////////////
@ -133,6 +133,24 @@ class SingleCollectionWriteTransaction : public SingleCollectionTransaction {
return this->create(this->trxCollection(), mptr, slice, nullptr, forceSync);
}
//////////////////////////////////////////////////////////////////////////////
/// @brief create a single document within a transaction, using shaped json
//////////////////////////////////////////////////////////////////////////////
int createDocument(TRI_voc_key_t key, TRI_doc_mptr_copy_t* mptr,
TRI_shaped_json_t const* shaped, bool forceSync) {
#ifdef TRI_ENABLE_MAINTAINER_MODE
if (_numWrites++ > N) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
#endif
TRI_ASSERT(mptr != nullptr);
return this->create(this->trxCollection(), key, 0, mptr, shaped, nullptr,
forceSync);
}
//////////////////////////////////////////////////////////////////////////////
/// @brief create a single edge within a transaction, using json
@ -170,24 +188,6 @@ class SingleCollectionWriteTransaction : public SingleCollectionTransaction {
return this->create(this->trxCollection(), mptr, slice, data, forceSync);
}
//////////////////////////////////////////////////////////////////////////////
/// @brief create a single document within a transaction, using shaped json
//////////////////////////////////////////////////////////////////////////////
int createDocument(TRI_voc_key_t key, TRI_doc_mptr_copy_t* mptr,
TRI_shaped_json_t const* shaped, bool forceSync) {
#ifdef TRI_ENABLE_MAINTAINER_MODE
if (_numWrites++ > N) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
#endif
TRI_ASSERT(mptr != nullptr);
return this->create(this->trxCollection(), key, 0, mptr, shaped, nullptr,
forceSync);
}
//////////////////////////////////////////////////////////////////////////////
/// @brief create a single edge within a transaction, using shaped json
//////////////////////////////////////////////////////////////////////////////

View File

@ -34,6 +34,119 @@ using namespace arangodb;
thread_local std::unordered_set<std::string>* Transaction::_makeNolockHeaders =
nullptr;
////////////////////////////////////////////////////////////////////////////////
/// @brief opens the declared collections of the transaction
////////////////////////////////////////////////////////////////////////////////
int Transaction::openCollections() {
if (_trx == nullptr) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (_setupState != TRI_ERROR_NO_ERROR) {
return _setupState;
}
if (!_isReal) {
return TRI_ERROR_NO_ERROR;
}
int res = TRI_EnsureCollectionsTransaction(_trx, _nestingLevel);
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief begin the transaction
////////////////////////////////////////////////////////////////////////////////
int Transaction::begin() {
if (_trx == nullptr) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (_setupState != TRI_ERROR_NO_ERROR) {
return _setupState;
}
if (!_isReal) {
if (_nestingLevel == 0) {
_trx->_status = TRI_TRANSACTION_RUNNING;
}
return TRI_ERROR_NO_ERROR;
}
int res = TRI_BeginTransaction(_trx, _hints, _nestingLevel);
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief commit / finish the transaction
////////////////////////////////////////////////////////////////////////////////
int Transaction::commit() {
if (_trx == nullptr || getStatus() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (!_isReal) {
if (_nestingLevel == 0) {
_trx->_status = TRI_TRANSACTION_COMMITTED;
}
return TRI_ERROR_NO_ERROR;
}
int res = TRI_CommitTransaction(_trx, _nestingLevel);
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief abort the transaction
////////////////////////////////////////////////////////////////////////////////
int Transaction::abort() {
if (_trx == nullptr || getStatus() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (!_isReal) {
if (_nestingLevel == 0) {
_trx->_status = TRI_TRANSACTION_ABORTED;
}
return TRI_ERROR_NO_ERROR;
}
int res = TRI_AbortTransaction(_trx, _nestingLevel);
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finish a transaction (commit or abort), based on the previous state
////////////////////////////////////////////////////////////////////////////////
int Transaction::finish(int errorNum) {
int res;
if (errorNum == TRI_ERROR_NO_ERROR) {
// there was no previous error, so we'll commit
res = this->commit();
} else {
// there was a previous error, so we'll abort
this->abort();
// return original error number
res = errorNum;
}
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief read all master pointers, using skip and limit and an internal

View File

@ -209,114 +209,31 @@ class Transaction {
/// @brief opens the declared collections of the transaction
//////////////////////////////////////////////////////////////////////////////
int openCollections() {
if (_trx == nullptr) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (_setupState != TRI_ERROR_NO_ERROR) {
return _setupState;
}
if (!_isReal) {
return TRI_ERROR_NO_ERROR;
}
int res = TRI_EnsureCollectionsTransaction(_trx, _nestingLevel);
return res;
}
int openCollections();
//////////////////////////////////////////////////////////////////////////////
/// @brief begin the transaction
//////////////////////////////////////////////////////////////////////////////
int begin() {
if (_trx == nullptr) {
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (_setupState != TRI_ERROR_NO_ERROR) {
return _setupState;
}
if (!_isReal) {
if (_nestingLevel == 0) {
_trx->_status = TRI_TRANSACTION_RUNNING;
}
return TRI_ERROR_NO_ERROR;
}
int res = TRI_BeginTransaction(_trx, _hints, _nestingLevel);
return res;
}
int begin();
//////////////////////////////////////////////////////////////////////////////
/// @brief commit / finish the transaction
//////////////////////////////////////////////////////////////////////////////
int commit() {
if (_trx == nullptr || getStatus() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (!_isReal) {
if (_nestingLevel == 0) {
_trx->_status = TRI_TRANSACTION_COMMITTED;
}
return TRI_ERROR_NO_ERROR;
}
int res = TRI_CommitTransaction(_trx, _nestingLevel);
return res;
}
int commit();
//////////////////////////////////////////////////////////////////////////////
/// @brief abort the transaction
//////////////////////////////////////////////////////////////////////////////
int abort() {
if (_trx == nullptr || getStatus() != TRI_TRANSACTION_RUNNING) {
// transaction not created or not running
return TRI_ERROR_TRANSACTION_INTERNAL;
}
if (!_isReal) {
if (_nestingLevel == 0) {
_trx->_status = TRI_TRANSACTION_ABORTED;
}
return TRI_ERROR_NO_ERROR;
}
int res = TRI_AbortTransaction(_trx, _nestingLevel);
return res;
}
int abort();
//////////////////////////////////////////////////////////////////////////////
/// @brief finish a transaction (commit or abort), based on the previous state
//////////////////////////////////////////////////////////////////////////////
int finish(int errorNum) {
int res;
if (errorNum == TRI_ERROR_NO_ERROR) {
// there was no previous error, so we'll commit
res = this->commit();
} else {
// there was a previous error, so we'll abort
this->abort();
// return original error number
res = errorNum;
}
return res;
}
int finish(int errorNum);
//////////////////////////////////////////////////////////////////////////////
/// @brief return the transaction collection for a document collection
@ -356,7 +273,7 @@ class Transaction {
return trxCollection->_ditch;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief read all master pointers, using skip and limit and an internal
/// offset into the primary index. this can be used for incremental access to
@ -382,6 +299,7 @@ class Transaction {
//////////////////////////////////////////////////////////////////////////////
/// @brief delete a single document
/// DEPRECATED
//////////////////////////////////////////////////////////////////////////////
int remove(TRI_transaction_collection_t* trxCollection,
@ -405,6 +323,7 @@ class Transaction {
//////////////////////////////////////////////////////////////////////////////
/// @brief create a single document, using JSON
/// DEPRECATED
//////////////////////////////////////////////////////////////////////////////
int create(TRI_transaction_collection_t* trxCollection,
@ -436,6 +355,7 @@ class Transaction {
//////////////////////////////////////////////////////////////////////////////
/// @brief create a single document, using VelocyPack
/// DEPRECATED
//////////////////////////////////////////////////////////////////////////////
int create(TRI_transaction_collection_t* trxCollection,
@ -453,6 +373,7 @@ class Transaction {
//////////////////////////////////////////////////////////////////////////////
/// @brief update a single document, using JSON
/// DEPRECATED
//////////////////////////////////////////////////////////////////////////////
int update(TRI_transaction_collection_t* trxCollection,
@ -481,6 +402,7 @@ class Transaction {
//////////////////////////////////////////////////////////////////////////////
/// @brief read a single document, identified by key
/// DEPRECATED
//////////////////////////////////////////////////////////////////////////////
int readSingle(TRI_transaction_collection_t* trxCollection,

View File

@ -567,8 +567,8 @@ static std::vector<std::string> GetCollectionNamesCluster(
/// @brief looks up a document and returns whether it exists
////////////////////////////////////////////////////////////////////////////////
static void ExistsVocbaseCol(bool useCollection,
v8::FunctionCallbackInfo<v8::Value> const& args) {
static void ExistsVocbaseVPack(bool useCollection,
v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
@ -1312,8 +1312,8 @@ static void InsertVocbaseVPack(
/// @brief updates (patches) a document
////////////////////////////////////////////////////////////////////////////////
static void UpdateVocbaseCol(bool useCollection,
v8::FunctionCallbackInfo<v8::Value> const& args) {
static void UpdateVocbaseVPack(bool useCollection,
v8::FunctionCallbackInfo<v8::Value> const& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
UpdateOptions options;
@ -1379,8 +1379,7 @@ static void UpdateVocbaseCol(bool useCollection,
if (useCollection) {
// called as db.collection.update()
col =
TRI_UnwrapClass<TRI_vocbase_col_t>(args.Holder(), WRP_VOCBASE_COL_TYPE);
col = TRI_UnwrapClass<TRI_vocbase_col_t>(args.Holder(), WRP_VOCBASE_COL_TYPE);
if (col == nullptr) {
TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection");
@ -1427,7 +1426,7 @@ static void UpdateVocbaseCol(bool useCollection,
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DOCUMENT_TYPE_INVALID);
}
TRI_json_t* json = TRI_ObjectToJson(isolate, args[1]);
std::unique_ptr<TRI_json_t> json(TRI_ObjectToJson(isolate, args[1]));
if (json == nullptr) {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_errno(), "<data> is no valid JSON");
@ -1438,7 +1437,6 @@ static void UpdateVocbaseCol(bool useCollection,
int res = trx.begin();
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION(res);
}
@ -1450,12 +1448,10 @@ static void UpdateVocbaseCol(bool useCollection,
res = trx.read(&mptr, key.get());
if (res != TRI_ERROR_NO_ERROR) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION(res);
}
if (trx.orderDitch(trx.trxCollection()) == nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION_MEMORY();
}
@ -1470,7 +1466,6 @@ static void UpdateVocbaseCol(bool useCollection,
&shaped); // PROTECTED by trx here
if (old == nullptr) {
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION_MEMORY();
}
@ -1478,10 +1473,9 @@ static void UpdateVocbaseCol(bool useCollection,
// compare attributes in shardKeys
std::string const cidString = StringUtils::itoa(document->_info.planId());
if (shardKeysChanged(col->_dbName, cidString, old, json, true)) {
if (shardKeysChanged(col->_dbName, cidString, old, json.get(), true)) {
TRI_FreeJson(document->getShaper()->memoryZone(),
old); // PROTECTED by trx here
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
TRI_V8_THROW_EXCEPTION(
TRI_ERROR_CLUSTER_MUST_NOT_CHANGE_SHARDING_ATTRIBUTES);
@ -1489,9 +1483,8 @@ static void UpdateVocbaseCol(bool useCollection,
}
TRI_json_t* patchedJson = TRI_MergeJson(
TRI_UNKNOWN_MEM_ZONE, old, json, !options.keepNull, options.mergeObjects);
TRI_UNKNOWN_MEM_ZONE, old, json.get(), !options.keepNull, options.mergeObjects);
TRI_FreeJson(zone, old);
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
if (patchedJson == nullptr) {
TRI_V8_THROW_EXCEPTION_MEMORY();
@ -1889,17 +1882,6 @@ static void RemoveVocbaseVPack(
/// @brief was docuBlock documentsCollectionName
////////////////////////////////////////////////////////////////////////////////
static void JS_DocumentVocbaseCol(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
DocumentVocbaseCol(true, args);
TRI_V8_TRY_CATCH_END
}
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock documentsCollectionName
////////////////////////////////////////////////////////////////////////////////
static void JS_DocumentVocbaseVPack(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
@ -1975,10 +1957,10 @@ static void JS_DropVocbaseCol(v8::FunctionCallbackInfo<v8::Value> const& args) {
/// @brief was docuBlock documentsCollectionExists
////////////////////////////////////////////////////////////////////////////////
static void JS_ExistsVocbaseCol(
static void JS_ExistsVocbaseVPack(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
return ExistsVocbaseCol(true, args);
return ExistsVocbaseVPack(true, args);
TRI_V8_TRY_CATCH_END
}
@ -2561,17 +2543,6 @@ static void JS_PropertiesVocbaseCol(
TRI_V8_TRY_CATCH_END
}
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock documentsCollectionRemove
////////////////////////////////////////////////////////////////////////////////
static void JS_RemoveVocbaseCol(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
return RemoveVocbaseCol(true, args);
TRI_V8_TRY_CATCH_END
}
static void JS_RemoveVocbaseVPack(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
@ -2792,10 +2763,10 @@ static void JS_RotateVocbaseCol(
/// @brief was docuBlock documentsCollectionUpdate
////////////////////////////////////////////////////////////////////////////////
static void JS_UpdateVocbaseCol(
static void JS_UpdateVocbaseVPack(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
return UpdateVocbaseCol(true, args);
return UpdateVocbaseVPack(true, args);
TRI_V8_TRY_CATCH_END
}
@ -3154,42 +3125,6 @@ static void InsertEdgeColCoordinator(
TRI_V8_RETURN(ret);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock documentsCollectionInsert
////////////////////////////////////////////////////////////////////////////////
static void JS_InsertVocbaseCol(
v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
v8::HandleScope scope(isolate);
TRI_vocbase_col_t* collection =
TRI_UnwrapClass<TRI_vocbase_col_t>(args.Holder(), WRP_VOCBASE_COL_TYPE);
if (collection == nullptr) {
TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection");
}
if (ServerState::instance()->isCoordinator()) {
// coordinator case
if ((TRI_col_type_e)collection->_type == TRI_COL_TYPE_DOCUMENT) {
InsertVocbaseColCoordinator(collection, 0, args);
return;
}
InsertEdgeColCoordinator(collection, 0, args);
return;
}
// single server case
if ((TRI_col_type_e)collection->_type == TRI_COL_TYPE_DOCUMENT) {
InsertVocbaseCol(collection, 0, args);
} else {
InsertEdgeCol(collection, 0, args);
}
TRI_V8_TRY_CATCH_END
}
////////////////////////////////////////////////////////////////////////////////
/// @brief __save(collection, document). This method is used internally and not
/// part of the public API
@ -3871,7 +3806,7 @@ static void JS_DocumentVocbase(
static void JS_ExistsVocbase(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
return ExistsVocbaseCol(false, args);
return ExistsVocbaseVPack(false, args);
TRI_V8_TRY_CATCH_END
}
@ -3891,7 +3826,7 @@ static void JS_ReplaceVocbase(v8::FunctionCallbackInfo<v8::Value> const& args) {
static void JS_UpdateVocbase(v8::FunctionCallbackInfo<v8::Value> const& args) {
TRI_V8_TRY_CATCH_BEGIN(isolate);
return UpdateVocbaseCol(false, args);
return UpdateVocbaseVPack(false, args);
TRI_V8_TRY_CATCH_END
}
@ -4174,18 +4109,14 @@ void TRI_InitV8collection(v8::Handle<v8::Context> context, TRI_server_t* server,
JS_DatafilesVocbaseCol);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("datafileScan"),
JS_DatafileScanVocbaseCol, true);
// TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("document"),
// JS_DocumentVocbaseCol);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("document"),
JS_DocumentVocbaseVPack);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("drop"),
JS_DropVocbaseCol);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("exists"),
JS_ExistsVocbaseCol);
JS_ExistsVocbaseVPack);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("figures"),
JS_FiguresVocbaseCol);
// TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("insert"),
// JS_InsertVocbaseCol);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("insert"),
JS_InsertVocbaseVPack);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("load"),
@ -4198,8 +4129,6 @@ void TRI_InitV8collection(v8::Handle<v8::Context> context, TRI_server_t* server,
JS_PlanIdVocbaseCol);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("properties"),
JS_PropertiesVocbaseCol);
// TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("remove"),
// JS_RemoveVocbaseCol);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("remove"),
JS_RemoveVocbaseVPack);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("revision"),
@ -4226,7 +4155,7 @@ void TRI_InitV8collection(v8::Handle<v8::Context> context, TRI_server_t* server,
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("unload"),
JS_UnloadVocbaseCol);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("update"),
JS_UpdateVocbaseCol);
JS_UpdateVocbaseVPack);
TRI_AddMethodVocbase(isolate, rt, TRI_V8_ASCII_STRING("version"),
JS_VersionVocbaseCol);