mirror of https://gitee.com/bigwinds/arangodb
replication applier will now preferrably use collection names instead of collection ids when applying events
This commit is contained in:
parent
4f30db9eda
commit
79f70c7eea
25
CHANGELOG
25
CHANGELOG
|
@ -1,6 +1,31 @@
|
|||
v1.4
|
||||
----
|
||||
|
||||
* only the following system collections will be excluded from replication from now on:
|
||||
- `_replication`
|
||||
- `_trx`
|
||||
- `_users`
|
||||
- `_aal`
|
||||
- `_fishbowl`
|
||||
- `_modules`
|
||||
- `_routing`
|
||||
|
||||
Especially the following system collections will now be included in replication:
|
||||
- `_aqlfunctions`
|
||||
- `_graphs`
|
||||
|
||||
In previous versions of ArangoDB, all system collections were excluded from the
|
||||
replication.
|
||||
|
||||
The change also caused a change in the replication logger and applier:
|
||||
in previous versions of ArangoDB, only a collection's id was logged for an operation.
|
||||
This has not caused problems for non-system collections but for system collections
|
||||
there ids might differ. In addition to a collection id ArangoDB will now also log the
|
||||
name of a collection for each replication event.
|
||||
|
||||
The replication applier will now look for the collection name attribute in logged
|
||||
events preferrably.
|
||||
|
||||
* added database selection to arango-dfdb
|
||||
|
||||
* provide foxx-manager, arangodump, and arangorestore in Windows build
|
||||
|
|
|
@ -17,9 +17,11 @@ This specialised interface intentionally does not provide all functionality
|
|||
that is available in the regular document REST API.
|
||||
|
||||
Operations on users may become more restricted than regular document operations,
|
||||
and extra privilege and security security checks may be introduced in the
|
||||
and extra privileges and security security checks may be introduced in the
|
||||
future for this interface.
|
||||
|
||||
Please note that user operations are not included in ArangoDB's replication.
|
||||
|
||||
@anchor HttpUserSave
|
||||
@copydetails JSF_post_api_user
|
||||
|
||||
|
|
|
@ -257,6 +257,13 @@ If you want the `foxx-manager` to work in the context of a different database,
|
|||
use the command-line argument `--server.database <database-name>` when invoking
|
||||
the `foxx-manager` binary.
|
||||
|
||||
Foxx Applications and Replication {#UserManualFoxxManagerReplication}
|
||||
=====================================================================
|
||||
|
||||
Foxx applications consist of a file system part (scripts in the application directory)
|
||||
and a database part. The current version of ArangoDB cannot replicate changes in the
|
||||
file system so installing, updating or removing a Foxx application using `foxx-manager`
|
||||
will not be included in the replication.
|
||||
|
||||
Foxx Manager Commands {#UserManualFoxxManagerCommands}
|
||||
======================================================
|
||||
|
|
|
@ -6,5 +6,6 @@ TOC {#UserManualFoxxManagerTOC}
|
|||
- @ref UserManualFoxxManagerFirstSteps
|
||||
- @ref UserManualFoxxManagerBehindScences
|
||||
- @ref UserManualFoxxManagerDatabases
|
||||
- @ref UserManualFoxxManagerReplication
|
||||
- @ref UserManualFoxxManagerCommands
|
||||
- @ref UserManualFoxxManagerOptions
|
||||
|
|
|
@ -570,9 +570,16 @@ limitations may be removed in later versions of ArangoDB:
|
|||
operations on a slave. ArangoDB currently does not prevent users from carrying out
|
||||
their own write operations on slaves, though this might lead to undefined behavior
|
||||
and the replication applier stopping.
|
||||
- the replication logger will only log write operations for non-system collections.
|
||||
Write operations for system collections are currently not logged, and thus will not
|
||||
be shipped to slaves.
|
||||
- the replication logger will log write operations for all user-defined collections and
|
||||
only some system collections. Write operations for the following system collections
|
||||
are excluded intentionally: `_trx`, `_replication`, `_users`, `_aal`, `_fishbowl`,
|
||||
`_modules` and `_routing`. Write operations for the following system collections
|
||||
will be logged: `_aqlfunctions`, `_graphs`.
|
||||
- Foxx applications consist of database entries and application scripts in the file system.
|
||||
The file system parts of Foxx applications are not tracked anywhere and thus not
|
||||
replicated in current versions of ArangoDB. To replicate a Foxx application, it is
|
||||
required to copy the application to the remote server and install it there using the
|
||||
`foxx-manager` utility.
|
||||
- master servers do not know which slaves are or will be connected to them. All servers
|
||||
in a replication setup are currently only loosely coupled. There currently is no way
|
||||
for a client to query which servers are present in a replication.
|
||||
|
|
|
@ -390,7 +390,7 @@ describe ArangoDB do
|
|||
################################################################################
|
||||
|
||||
it "checks the initial inventory" do
|
||||
cmd = api + "/inventory"
|
||||
cmd = api + "/inventory?includeSystem=false"
|
||||
doc = ArangoDB.log_get("#{prefix}-inventory", cmd, :body => "")
|
||||
|
||||
doc.code.should eq(200)
|
||||
|
@ -409,7 +409,7 @@ describe ArangoDB do
|
|||
cid = ArangoDB.create_collection("UnitTestsReplication", false)
|
||||
cid2 = ArangoDB.create_collection("UnitTestsReplication2", true, 3)
|
||||
|
||||
cmd = api + "/inventory"
|
||||
cmd = api + "/inventory?includeSystem=false"
|
||||
doc = ArangoDB.log_get("#{prefix}-inventory", cmd, :body => "")
|
||||
doc.code.should eq(200)
|
||||
|
||||
|
@ -808,14 +808,6 @@ describe ArangoDB do
|
|||
|
||||
i.should be < 100
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
it "checks the dump for a collection with deleted documents" do
|
||||
cid = ArangoDB.create_collection("UnitTestsReplication", false)
|
||||
|
|
|
@ -331,13 +331,27 @@ int ContinuousSyncer::processDocument (TRI_replication_operation_e type,
|
|||
string& errorMsg) {
|
||||
updateTick = false;
|
||||
|
||||
// extract "cid"
|
||||
TRI_voc_cid_t cid = getCid(json);
|
||||
// extract "cname"
|
||||
const string cname = JsonHelper::getStringValue(json, "cname", "");
|
||||
TRI_voc_cid_t cid = 0;
|
||||
|
||||
if (! cname.empty()) {
|
||||
TRI_vocbase_col_t const* col = TRI_LookupCollectionByNameVocBase(_vocbase, cname.c_str());
|
||||
|
||||
if (col != 0) {
|
||||
cid = col->_cid;
|
||||
}
|
||||
}
|
||||
|
||||
if (cid == 0) {
|
||||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
cid = getCid(json);
|
||||
}
|
||||
|
||||
|
||||
if (cid == 0) {
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
// extract "key"
|
||||
TRI_json_t const* keyJson = JsonHelper::getArrayElement(json, "key");
|
||||
|
||||
|
@ -496,17 +510,31 @@ int ContinuousSyncer::startTransaction (TRI_json_t const* json) {
|
|||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
TRI_voc_cid_t cid = getCid(collection);
|
||||
|
||||
if (cid == 0) {
|
||||
TRI_FreeTransaction(trx);
|
||||
|
||||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
uint64_t numOperations = JsonHelper::getNumericValue<uint64_t>(collection, "operations", 0);
|
||||
|
||||
if (numOperations > 0) {
|
||||
// extract collection name
|
||||
const string cname = JsonHelper::getStringValue(collection, "name", "");
|
||||
TRI_voc_cid_t cid = 0;
|
||||
|
||||
if (! cname.empty()) {
|
||||
TRI_vocbase_col_t* col = TRI_LookupCollectionByNameVocBase(_vocbase, cname.c_str());
|
||||
|
||||
if (col != 0) {
|
||||
cid = col->_cid;
|
||||
}
|
||||
}
|
||||
|
||||
if (cid == 0) {
|
||||
cid = getCid(collection);
|
||||
}
|
||||
|
||||
if (cid == 0) {
|
||||
TRI_FreeTransaction(trx);
|
||||
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
res = TRI_AddCollectionTransaction(trx, cid, TRI_TRANSACTION_WRITE, TRI_TRANSACTION_TOP_LEVEL);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -576,12 +604,6 @@ int ContinuousSyncer::commitTransaction (TRI_json_t const* json) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int ContinuousSyncer::renameCollection (TRI_json_t const* json) {
|
||||
const TRI_voc_cid_t cid = getCid(json);
|
||||
|
||||
if (cid == 0) {
|
||||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
TRI_json_t const* collectionJson = TRI_LookupArrayJson(json, "collection");
|
||||
const string name = JsonHelper::getStringValue(collectionJson, "name", "");
|
||||
|
||||
|
@ -589,7 +611,17 @@ int ContinuousSyncer::renameCollection (TRI_json_t const* json) {
|
|||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
TRI_vocbase_col_t* col = TRI_LookupCollectionByIdVocBase(_vocbase, cid);
|
||||
const string cname = JsonHelper::getStringValue(json, "cname", "");
|
||||
TRI_vocbase_col_t* col = 0;
|
||||
|
||||
if (! cname.empty()) {
|
||||
col = TRI_LookupCollectionByNameVocBase(_vocbase, cname.c_str());
|
||||
}
|
||||
|
||||
if (col == 0) {
|
||||
TRI_voc_cid_t cid = getCid(json);
|
||||
col = TRI_LookupCollectionByIdVocBase(_vocbase, cid);
|
||||
}
|
||||
|
||||
if (col == 0) {
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
|
|
|
@ -226,9 +226,11 @@ TRI_voc_cid_t Syncer::getCid (TRI_json_t const* json) const {
|
|||
TRI_json_t const* id = JsonHelper::getArrayElement(json, "cid");
|
||||
|
||||
if (JsonHelper::isString(id)) {
|
||||
// string cid, e.g. "9988488"
|
||||
return StringUtils::uint64(id->_value._string.data, id->_value._string.length - 1);
|
||||
}
|
||||
else if (JsonHelper::isNumber(id)) {
|
||||
// numeric cid, e.g. 9988488
|
||||
return (TRI_voc_cid_t) id->_value._number;
|
||||
}
|
||||
|
||||
|
@ -286,15 +288,16 @@ int Syncer::applyCollectionDumpMarker (TRI_transaction_collection_t* trxCollecti
|
|||
const string from = JsonHelper::getStringValue(json, TRI_VOC_ATTRIBUTE_FROM, "");
|
||||
const string to = JsonHelper::getStringValue(json, TRI_VOC_ATTRIBUTE_TO, "");
|
||||
|
||||
CollectionNameResolver resolver(_vocbase);
|
||||
|
||||
// parse _from
|
||||
TRI_document_edge_t edge;
|
||||
if (! DocumentHelper::parseDocumentId(from.c_str(), edge._fromCid, &edge._fromKey)) {
|
||||
if (! DocumentHelper::parseDocumentId(resolver, from.c_str(), edge._fromCid, &edge._fromKey)) {
|
||||
res = TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD;
|
||||
}
|
||||
|
||||
// parse _to
|
||||
if (! DocumentHelper::parseDocumentId(to.c_str(), edge._toCid, &edge._toKey)) {
|
||||
if (! DocumentHelper::parseDocumentId(resolver, to.c_str(), edge._toCid, &edge._toKey)) {
|
||||
res = TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD;
|
||||
}
|
||||
|
||||
|
@ -384,13 +387,17 @@ int Syncer::createCollection (TRI_json_t const* json,
|
|||
|
||||
TRI_vocbase_col_t* col = TRI_LookupCollectionByIdVocBase(_vocbase, cid);
|
||||
|
||||
if (col == 0) {
|
||||
// try looking up the collection by name then
|
||||
col = TRI_LookupCollectionByNameVocBase(_vocbase, name.c_str());
|
||||
}
|
||||
|
||||
if (col != 0 &&
|
||||
(TRI_col_type_t) col->_type == (TRI_col_type_t) type) {
|
||||
// collection already exists. TODO: compare attributes
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
TRI_json_t* keyOptions = 0;
|
||||
|
||||
if (JsonHelper::isArray(JsonHelper::getArrayElement(json, "keyOptions"))) {
|
||||
|
@ -455,13 +462,17 @@ int Syncer::createCollection (TRI_json_t const* json,
|
|||
|
||||
int Syncer::dropCollection (TRI_json_t const* json,
|
||||
bool reportError) {
|
||||
const TRI_voc_cid_t cid = getCid(json);
|
||||
const string cname = JsonHelper::getStringValue(json, "cname", "");
|
||||
TRI_vocbase_col_t* col = 0;
|
||||
|
||||
if (cid == 0) {
|
||||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
if (! cname.empty()) {
|
||||
col = TRI_LookupCollectionByNameVocBase(_vocbase, cname.c_str());
|
||||
}
|
||||
|
||||
TRI_vocbase_col_t* col = TRI_LookupCollectionByIdVocBase(_vocbase, cid);
|
||||
if (col == 0) {
|
||||
TRI_voc_cid_t cid = getCid(json);
|
||||
col = TRI_LookupCollectionByIdVocBase(_vocbase, cid);
|
||||
}
|
||||
|
||||
if (col == 0) {
|
||||
if (reportError) {
|
||||
|
@ -479,19 +490,23 @@ int Syncer::dropCollection (TRI_json_t const* json,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int Syncer::createIndex (TRI_json_t const* json) {
|
||||
const TRI_voc_cid_t cid = getCid(json);
|
||||
|
||||
if (cid == 0) {
|
||||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
TRI_json_t const* indexJson = JsonHelper::getArrayElement(json, "index");
|
||||
|
||||
if (! JsonHelper::isArray(indexJson)) {
|
||||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
TRI_vocbase_col_t* col = TRI_UseCollectionByIdVocBase(_vocbase, cid);
|
||||
const string cname = JsonHelper::getStringValue(json, "cname", "");
|
||||
TRI_vocbase_col_t* col = 0;
|
||||
|
||||
if (! cname.empty()) {
|
||||
col = TRI_UseCollectionByNameVocBase(_vocbase, cname.c_str());
|
||||
}
|
||||
|
||||
if (col == 0) {
|
||||
TRI_voc_cid_t cid = getCid(json);
|
||||
col = TRI_UseCollectionByIdVocBase(_vocbase, cid);
|
||||
}
|
||||
|
||||
if (col == 0 || col->_collection == 0) {
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
|
@ -520,12 +535,6 @@ int Syncer::createIndex (TRI_json_t const* json) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int Syncer::dropIndex (TRI_json_t const* json) {
|
||||
const TRI_voc_cid_t cid = getCid(json);
|
||||
|
||||
if (cid == 0) {
|
||||
return TRI_ERROR_REPLICATION_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
const string id = JsonHelper::getStringValue(json, "id", "");
|
||||
|
||||
if (id.empty()) {
|
||||
|
@ -533,8 +542,18 @@ int Syncer::dropIndex (TRI_json_t const* json) {
|
|||
}
|
||||
|
||||
const TRI_idx_iid_t iid = StringUtils::uint64(id);
|
||||
|
||||
const string cname = JsonHelper::getStringValue(json, "cname", "");
|
||||
TRI_vocbase_col_t* col = 0;
|
||||
|
||||
TRI_vocbase_col_t* col = TRI_UseCollectionByIdVocBase(_vocbase, cid);
|
||||
if (! cname.empty()) {
|
||||
col = TRI_UseCollectionByNameVocBase(_vocbase, cname.c_str());
|
||||
}
|
||||
|
||||
if (col == 0) {
|
||||
TRI_voc_cid_t cid = getCid(json);
|
||||
col = TRI_UseCollectionByIdVocBase(_vocbase, cid);
|
||||
}
|
||||
|
||||
if (col == 0 || col->_collection == 0) {
|
||||
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
|
||||
|
|
|
@ -298,6 +298,12 @@ bool RestReplicationHandler::filterCollection (TRI_vocbase_col_t* collection,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool includeSystem = *((bool*) data);
|
||||
if (! includeSystem && collection->_name[0] == '_') {
|
||||
// exclude all system collections
|
||||
return false;
|
||||
}
|
||||
|
||||
// all other cases should be included
|
||||
return true;
|
||||
}
|
||||
|
@ -1381,11 +1387,8 @@ void RestReplicationHandler::handleCommandInventory () {
|
|||
includeSystem = StringUtils::boolean(value);
|
||||
}
|
||||
|
||||
// register filter function
|
||||
bool (*filter)(TRI_vocbase_col_t*, void*) = includeSystem ? 0 : &filterCollection;
|
||||
|
||||
// collections and indexes
|
||||
TRI_json_t* collections = TRI_InventoryCollectionsVocBase(_vocbase, tick, filter, NULL);
|
||||
TRI_json_t* collections = TRI_InventoryCollectionsVocBase(_vocbase, tick, &filterCollection, (void*) &includeSystem);
|
||||
|
||||
if (collections == 0) {
|
||||
generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -1518,6 +1521,7 @@ int RestReplicationHandler::createCollection (TRI_json_t const* json,
|
|||
params._doCompact = JsonHelper::getBooleanValue(json, "doCompact", true);
|
||||
params._waitForSync = JsonHelper::getBooleanValue(json, "waitForSync", _vocbase->_settings.defaultWaitForSync);
|
||||
params._isVolatile = JsonHelper::getBooleanValue(json, "isVolatile", false);
|
||||
params._isSystem = (name[0] == '_');
|
||||
|
||||
if (cid > 0) {
|
||||
// wait for "old" collection to be dropped
|
||||
|
|
|
@ -2225,8 +2225,9 @@ static v8::Handle<v8::Value> JS_ByConditionBitarray (v8::Arguments const& argv)
|
|||
}
|
||||
|
||||
typedef struct collection_checksum_s {
|
||||
TRI_string_buffer_t _buffer;
|
||||
uint32_t _checksum;
|
||||
TRI_string_buffer_t _buffer;
|
||||
CollectionNameResolver* _resolver;
|
||||
uint32_t _checksum;
|
||||
}
|
||||
collection_checksum_t;
|
||||
|
||||
|
@ -2255,9 +2256,9 @@ template<bool WR, bool WD> static bool ChecksumCalculator (TRI_doc_mptr_t const*
|
|||
if (WR) {
|
||||
localCrc += TRI_Crc32HashPointer(&mptr->_rid, sizeof(TRI_voc_rid_t));
|
||||
}
|
||||
const string extra = StringUtils::itoa(e->_toCid) + string(((char*) marker) + e->_offsetToKey) +
|
||||
StringUtils::itoa(e->_fromCid) + string(((char*) marker) + e->_offsetFromKey);
|
||||
|
||||
const string extra = helper->_resolver->getCollectionName(e->_toCid) + TRI_DOCUMENT_HANDLE_SEPARATOR_CHR + string(((char*) marker) + e->_offsetToKey) +
|
||||
helper->_resolver->getCollectionName(e->_fromCid) + TRI_DOCUMENT_HANDLE_SEPARATOR_CHR + string(((char*) marker) + e->_offsetFromKey);
|
||||
|
||||
localCrc += TRI_Crc32HashPointer(extra.c_str(), extra.size());
|
||||
}
|
||||
else {
|
||||
|
@ -2332,6 +2333,7 @@ static v8::Handle<v8::Value> JS_ChecksumCollection (v8::Arguments const& argv) {
|
|||
|
||||
collection_checksum_t helper;
|
||||
helper._checksum = 0;
|
||||
helper._resolver = &resolver;
|
||||
|
||||
// .............................................................................
|
||||
// inside a read transaction
|
||||
|
|
|
@ -65,8 +65,24 @@ void TRI_GetTimeStampReplication (char* dst,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TRI_ExcludeCollectionReplication (const char* name) {
|
||||
// exclude all invalid & system collections
|
||||
if (name == NULL || *name == '_') {
|
||||
if (name == NULL) {
|
||||
// name invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
if (*name != '_') {
|
||||
// all regular collections are included
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TRI_EqualString(name, TRI_COL_NAME_REPLICATION) ||
|
||||
TRI_EqualString(name, TRI_COL_NAME_TRANSACTION) ||
|
||||
TRI_EqualString(name, TRI_COL_NAME_USERS) ||
|
||||
TRI_EqualString(name, "_aal") ||
|
||||
TRI_EqualString(name, "_fishbowl") ||
|
||||
TRI_EqualString(name, "_modules") ||
|
||||
TRI_EqualString(name, "_routing")) {
|
||||
// these system collections will be excluded
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,6 +255,30 @@ static TRI_replication_operation_e TranslateDocumentOperation (TRI_voc_document_
|
|||
return REPLICATION_INVALID;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief append a collection name or id to a string buffer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool AppendCollection (TRI_replication_logger_t* logger,
|
||||
TRI_string_buffer_t* buffer,
|
||||
TRI_voc_cid_t cid) {
|
||||
if (cid > 0) {
|
||||
char* name;
|
||||
|
||||
name = TRI_GetCollectionNameByIdVocBase(logger->_vocbase, cid);
|
||||
|
||||
if (name != NULL) {
|
||||
APPEND_STRING(buffer, name);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, name);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
APPEND_STRING(buffer, "_unknown");
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief free the logger's cap constraint
|
||||
/// the function must called under the statusLock
|
||||
|
@ -526,13 +550,16 @@ static int LogEvent (TRI_replication_logger_t* logger,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool StringifyCollection (TRI_string_buffer_t* buffer,
|
||||
const TRI_voc_cid_t cid) {
|
||||
const TRI_voc_cid_t cid,
|
||||
char const* name) {
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
APPEND_STRING(buffer, "\"cid\":\"");
|
||||
APPEND_UINT64(buffer, (uint64_t) cid);
|
||||
APPEND_STRING(buffer, "\",\"cname\":\"");
|
||||
APPEND_STRING(buffer, name);
|
||||
APPEND_CHAR(buffer, '"');
|
||||
|
||||
return true;
|
||||
|
@ -561,6 +588,7 @@ static bool StringifyTickReplication (TRI_string_buffer_t* buffer,
|
|||
|
||||
static bool StringifyCreateCollection (TRI_string_buffer_t* buffer,
|
||||
TRI_voc_cid_t cid,
|
||||
char const* name,
|
||||
TRI_json_t const* json) {
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
|
@ -568,6 +596,8 @@ static bool StringifyCreateCollection (TRI_string_buffer_t* buffer,
|
|||
|
||||
APPEND_STRING(buffer, "{\"cid\":\"");
|
||||
APPEND_UINT64(buffer, (uint64_t) cid);
|
||||
APPEND_STRING(buffer, "\",\"cname\":\"");
|
||||
APPEND_STRING(buffer, name);
|
||||
APPEND_STRING(buffer, "\",\"collection\":");
|
||||
APPEND_JSON(buffer, json);
|
||||
APPEND_CHAR(buffer, '}');
|
||||
|
@ -580,14 +610,15 @@ static bool StringifyCreateCollection (TRI_string_buffer_t* buffer,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool StringifyDropCollection (TRI_string_buffer_t* buffer,
|
||||
TRI_voc_cid_t cid) {
|
||||
TRI_voc_cid_t cid,
|
||||
char const* name) {
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
APPEND_CHAR(buffer, '{');
|
||||
|
||||
if (! StringifyCollection(buffer, cid)) {
|
||||
if (! StringifyCollection(buffer, cid, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -602,7 +633,8 @@ static bool StringifyDropCollection (TRI_string_buffer_t* buffer,
|
|||
|
||||
static bool StringifyRenameCollection (TRI_string_buffer_t* buffer,
|
||||
TRI_voc_cid_t cid,
|
||||
char const* name) {
|
||||
char const* name,
|
||||
char const* newName) {
|
||||
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
|
@ -610,13 +642,13 @@ static bool StringifyRenameCollection (TRI_string_buffer_t* buffer,
|
|||
|
||||
APPEND_CHAR(buffer, '{');
|
||||
|
||||
if (! StringifyCollection(buffer, cid)) {
|
||||
if (! StringifyCollection(buffer, cid, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
APPEND_STRING(buffer, ",\"collection\":{\"name\":\"");
|
||||
// name is user-defined, but does not need escaping as collection names are "safe"
|
||||
APPEND_STRING(buffer, name);
|
||||
APPEND_STRING(buffer, newName);
|
||||
APPEND_STRING(buffer, "\"}}");
|
||||
|
||||
return true;
|
||||
|
@ -628,6 +660,7 @@ static bool StringifyRenameCollection (TRI_string_buffer_t* buffer,
|
|||
|
||||
static bool StringifyCreateIndex (TRI_string_buffer_t* buffer,
|
||||
TRI_voc_cid_t cid,
|
||||
char const* name,
|
||||
TRI_json_t const* json) {
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
|
@ -635,7 +668,7 @@ static bool StringifyCreateIndex (TRI_string_buffer_t* buffer,
|
|||
|
||||
APPEND_CHAR(buffer, '{');
|
||||
|
||||
if (! StringifyCollection(buffer, cid)) {
|
||||
if (! StringifyCollection(buffer, cid, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -652,6 +685,7 @@ static bool StringifyCreateIndex (TRI_string_buffer_t* buffer,
|
|||
|
||||
static bool StringifyDropIndex (TRI_string_buffer_t* buffer,
|
||||
TRI_voc_cid_t cid,
|
||||
char const* name,
|
||||
TRI_idx_iid_t iid) {
|
||||
if (buffer == NULL) {
|
||||
return false;
|
||||
|
@ -659,7 +693,7 @@ static bool StringifyDropIndex (TRI_string_buffer_t* buffer,
|
|||
|
||||
APPEND_CHAR(buffer, '{');
|
||||
|
||||
if (! StringifyCollection(buffer, cid)) {
|
||||
if (! StringifyCollection(buffer, cid, name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -674,7 +708,8 @@ static bool StringifyDropIndex (TRI_string_buffer_t* buffer,
|
|||
/// @brief stringify a document operation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool StringifyDocumentOperation (TRI_string_buffer_t* buffer,
|
||||
static bool StringifyDocumentOperation (TRI_replication_logger_t* logger,
|
||||
TRI_string_buffer_t* buffer,
|
||||
TRI_document_collection_t* document,
|
||||
TRI_voc_document_operation_e type,
|
||||
TRI_df_marker_t const* marker,
|
||||
|
@ -714,7 +749,7 @@ static bool StringifyDocumentOperation (TRI_string_buffer_t* buffer,
|
|||
APPEND_CHAR(buffer, '{');
|
||||
|
||||
if (withCid) {
|
||||
if (! StringifyCollection(buffer, document->base.base._info._cid)) {
|
||||
if (! StringifyCollection(buffer, document->base.base._info._cid, document->base.base._info._name)) {
|
||||
return false;
|
||||
}
|
||||
APPEND_CHAR(buffer, ',');
|
||||
|
@ -771,12 +806,16 @@ static bool StringifyDocumentOperation (TRI_string_buffer_t* buffer,
|
|||
TRI_voc_key_t toKey = ((char*) e) + e->_offsetToKey;
|
||||
|
||||
APPEND_STRING(buffer, ",\"" TRI_VOC_ATTRIBUTE_FROM "\":\"");
|
||||
APPEND_UINT64(buffer, (uint64_t) e->_fromCid);
|
||||
APPEND_CHAR(buffer, '/');
|
||||
if (! AppendCollection(logger, buffer, e->_fromCid)) {
|
||||
return false;
|
||||
}
|
||||
APPEND_STRING(buffer, "\\/");
|
||||
APPEND_STRING(buffer, fromKey);
|
||||
APPEND_STRING(buffer, "\",\"" TRI_VOC_ATTRIBUTE_TO "\":\"");
|
||||
APPEND_UINT64(buffer, (uint64_t) e->_toCid);
|
||||
APPEND_CHAR(buffer, '/');
|
||||
if (! AppendCollection(logger, buffer, e->_toCid)) {
|
||||
return false;
|
||||
}
|
||||
APPEND_STRING(buffer, "\\/");
|
||||
APPEND_STRING(buffer, toKey);
|
||||
APPEND_CHAR(buffer, '"');
|
||||
}
|
||||
|
@ -1219,7 +1258,8 @@ static int HandleTransaction (TRI_replication_logger_t* logger,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyDocumentOperation(buffer,
|
||||
if (! StringifyDocumentOperation(logger,
|
||||
buffer,
|
||||
document,
|
||||
trxOperation->_type,
|
||||
trxOperation->_marker,
|
||||
|
@ -1891,7 +1931,7 @@ int TRI_LogCreateCollectionReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyCreateCollection(buffer, cid, json)) {
|
||||
if (! StringifyCreateCollection(buffer, cid, name, json)) {
|
||||
ReturnBuffer(logger, buffer);
|
||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
||||
|
||||
|
@ -1928,7 +1968,7 @@ int TRI_LogDropCollectionReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyDropCollection(buffer, cid)) {
|
||||
if (! StringifyDropCollection(buffer, cid, name)) {
|
||||
ReturnBuffer(logger, buffer);
|
||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
||||
|
||||
|
@ -1947,13 +1987,14 @@ int TRI_LogDropCollectionReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
int TRI_LogRenameCollectionReplication (TRI_vocbase_t* vocbase,
|
||||
TRI_voc_cid_t cid,
|
||||
char const* name,
|
||||
char const* oldName,
|
||||
char const* newName,
|
||||
TRI_server_id_t generatingServer) {
|
||||
TRI_string_buffer_t* buffer;
|
||||
TRI_replication_logger_t* logger;
|
||||
int res;
|
||||
|
||||
if (TRI_ExcludeCollectionReplication(name)) {
|
||||
if (TRI_ExcludeCollectionReplication(oldName)) {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1965,7 +2006,7 @@ int TRI_LogRenameCollectionReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyRenameCollection(buffer, cid, name)) {
|
||||
if (! StringifyRenameCollection(buffer, cid, oldName, newName)) {
|
||||
ReturnBuffer(logger, buffer);
|
||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
||||
|
||||
|
@ -2003,7 +2044,7 @@ int TRI_LogChangePropertiesCollectionReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyCreateCollection(buffer, cid, json)) {
|
||||
if (! StringifyCreateCollection(buffer, cid, name, json)) {
|
||||
ReturnBuffer(logger, buffer);
|
||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
||||
|
||||
|
@ -2042,7 +2083,7 @@ int TRI_LogCreateIndexReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyCreateIndex(buffer, cid, json)) {
|
||||
if (! StringifyCreateIndex(buffer, cid, name, json)) {
|
||||
ReturnBuffer(logger, buffer);
|
||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
||||
|
||||
|
@ -2080,7 +2121,7 @@ int TRI_LogDropIndexReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyDropIndex(buffer, cid, iid)) {
|
||||
if (! StringifyDropIndex(buffer, cid, name, iid)) {
|
||||
ReturnBuffer(logger, buffer);
|
||||
TRI_ReadUnlockReadWriteLock(&logger->_statusLock);
|
||||
|
||||
|
@ -2106,9 +2147,12 @@ int TRI_LogDocumentReplication (TRI_vocbase_t* vocbase,
|
|||
TRI_string_buffer_t* buffer;
|
||||
TRI_replication_logger_t* logger;
|
||||
TRI_replication_operation_e type;
|
||||
char* name;
|
||||
int res;
|
||||
|
||||
name = document->base.base._info._name;
|
||||
|
||||
if (TRI_ExcludeCollectionReplication(document->base.base._info._name)) {
|
||||
if (TRI_ExcludeCollectionReplication(name)) {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -2127,7 +2171,8 @@ int TRI_LogDocumentReplication (TRI_vocbase_t* vocbase,
|
|||
|
||||
buffer = GetBuffer(logger);
|
||||
|
||||
if (! StringifyDocumentOperation(buffer,
|
||||
if (! StringifyDocumentOperation(logger,
|
||||
buffer,
|
||||
document,
|
||||
docType,
|
||||
marker,
|
||||
|
|
|
@ -273,6 +273,7 @@ int TRI_LogDropCollectionReplication (struct TRI_vocbase_s*,
|
|||
int TRI_LogRenameCollectionReplication (struct TRI_vocbase_s*,
|
||||
TRI_voc_cid_t,
|
||||
char const*,
|
||||
char const*,
|
||||
TRI_server_id_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -800,7 +800,7 @@ static int RenameCollection (TRI_vocbase_t* vocbase,
|
|||
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
|
||||
|
||||
// stay inside the outer lock to protect against unloading
|
||||
TRI_LogRenameCollectionReplication(vocbase, collection->_cid, newName, generatingServer);
|
||||
TRI_LogRenameCollectionReplication(vocbase, collection->_cid, oldName, newName, generatingServer);
|
||||
|
||||
TRI_WRITE_UNLOCK_STATUS_VOCBASE_COL(collection);
|
||||
|
||||
|
|
|
@ -569,6 +569,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2, entry.collection.type);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(c._id, entry.collection.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertFalse(entry.collection.deleted);
|
||||
assertEqual(cn, entry.collection.name);
|
||||
},
|
||||
|
@ -599,6 +600,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2001, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -627,6 +629,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2002, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(cn2, entry.collection.name);
|
||||
},
|
||||
|
||||
|
@ -680,6 +683,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(c._id, entry.collection.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(cn, entry.collection.name);
|
||||
assertEqual(2, entry.collection.type);
|
||||
assertEqual(false, entry.collection.deleted);
|
||||
|
@ -687,6 +691,40 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(true, entry.collection.waitForSync);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test actions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testLoggerIncludedSystemCollection : function () {
|
||||
var state, tick, i;
|
||||
|
||||
replication.logger.start();
|
||||
|
||||
state = replication.logger.state().state;
|
||||
tick = state.lastLogTick;
|
||||
var count = getLogEntries();
|
||||
|
||||
c = db._collection("_graphs");
|
||||
var doc = c.save({ "test": 1 });
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 1, getLogEntries());
|
||||
|
||||
var entry = getLastLogEntry();
|
||||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(c.name(), entry.cname);
|
||||
|
||||
c.remove(doc._key);
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2302, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(c.name(), entry.cname);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test actions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -705,55 +743,95 @@ function ReplicationLoggerSuite () {
|
|||
var c = db._create("_unittests", { isSystem : true });
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 1, getLogEntries());
|
||||
var entry = getLastLogEntry();
|
||||
assertEqual(2000, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(c.name(), entry.cname);
|
||||
|
||||
c.properties({ waitForSync : true });
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 2, getLogEntries());
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2003, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(c.name(), entry.cname);
|
||||
|
||||
c.rename("_unitfoxx");
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 3, getLogEntries());
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2002, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual("_unittests", entry.cname);
|
||||
|
||||
c.rename("_unittests");
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 4, getLogEntries());
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2002, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual("_unitfoxx", entry.cname);
|
||||
|
||||
for (i = 0; i < 100; ++i) {
|
||||
c.save({ "_key" : "test" + i });
|
||||
}
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 104, getLogEntries());
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual("_unittests", entry.cname);
|
||||
|
||||
for (i = 0; i < 50; ++i) {
|
||||
c.remove("test" + i);
|
||||
}
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 154, getLogEntries());
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2302, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual("_unittests", entry.cname);
|
||||
|
||||
c.truncate();
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 206, getLogEntries());
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2201, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.collections[0].cid);
|
||||
assertEqual("_unittests", entry.collections[0].name);
|
||||
|
||||
db._drop("_unittests");
|
||||
db._drop("_unitfoxx");
|
||||
|
||||
state = replication.logger.state().state;
|
||||
assertEqual(tick, state.lastLogTick);
|
||||
assertEqual(count, getLogEntries());
|
||||
assertEqual(1, compareTicks(state.lastLogTick, tick));
|
||||
assertEqual(count + 207, getLogEntries());
|
||||
entry = getLastLogEntry();
|
||||
assertEqual(2001, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual("_unittests", entry.cname);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -808,6 +886,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
assertTrue(entry.tid != "");
|
||||
var tid = entry.tid;
|
||||
|
@ -819,6 +898,8 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual("abc", entry.key);
|
||||
assertEqual(rev, entry.oldRev);
|
||||
assertEqual(tid, entry.tid);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
|
||||
// commit
|
||||
entry = entries.pop();
|
||||
|
@ -826,6 +907,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
assertEqual(tid, entry.tid);
|
||||
},
|
||||
|
@ -883,6 +965,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("hash", entry.index.type);
|
||||
assertEqual(true, entry.index.unique);
|
||||
|
@ -916,6 +999,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("hash", entry.index.type);
|
||||
assertEqual(false, entry.index.unique);
|
||||
|
@ -949,6 +1033,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("skiplist", entry.index.type);
|
||||
assertEqual(false, entry.index.unique);
|
||||
|
@ -982,6 +1067,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("skiplist", entry.index.type);
|
||||
assertEqual(true, entry.index.unique);
|
||||
|
@ -1015,6 +1101,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("fulltext", entry.index.type);
|
||||
assertEqual(false, entry.index.unique);
|
||||
|
@ -1049,6 +1136,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("geo2", entry.index.type);
|
||||
assertEqual(false, entry.index.unique);
|
||||
|
@ -1083,6 +1171,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("geo1", entry.index.type);
|
||||
assertEqual(false, entry.index.unique);
|
||||
|
@ -1117,6 +1206,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("geo2", entry.index.type);
|
||||
assertEqual(true, entry.index.unique);
|
||||
|
@ -1152,6 +1242,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("geo2", entry.index.type);
|
||||
assertEqual(true, entry.index.unique);
|
||||
|
@ -1187,6 +1278,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("geo1", entry.index.type);
|
||||
assertEqual(true, entry.index.unique);
|
||||
|
@ -1221,6 +1313,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("cap", entry.index.type);
|
||||
assertEqual(false, entry.index.unique);
|
||||
|
@ -1255,6 +1348,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2100, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.index.id);
|
||||
assertEqual("cap", entry.index.type);
|
||||
assertEqual(false, entry.index.unique);
|
||||
|
@ -1289,6 +1383,7 @@ function ReplicationLoggerSuite () {
|
|||
assertTrue(2101, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual(idx.id.replace(/^.*\//, ''), entry.id);
|
||||
},
|
||||
|
||||
|
@ -1319,6 +1414,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual("abc", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -1339,6 +1435,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual("12345", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -1413,6 +1510,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2302, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual(rev, entry.oldRev);
|
||||
|
||||
|
@ -1431,6 +1529,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2302, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual(rev, entry.oldRev);
|
||||
|
||||
|
@ -1479,6 +1578,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual(oldRev, entry.oldRev);
|
||||
assertEqual("abc", entry.data._key);
|
||||
|
@ -1501,6 +1601,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual(oldRev, entry.oldRev);
|
||||
assertEqual("abc", entry.data._key);
|
||||
|
@ -1570,6 +1671,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual(oldRev, entry.oldRev);
|
||||
assertEqual("abc", entry.data._key);
|
||||
|
@ -1646,8 +1748,11 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2301, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(e._id, entry.cid);
|
||||
assertEqual(cn2, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual("abc", entry.data._key);
|
||||
assertEqual(cn + "/test1", entry.data._from);
|
||||
assertEqual(cn + "/test2", entry.data._to);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
assertEqual(1, entry.data.test);
|
||||
|
||||
|
@ -1666,8 +1771,11 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2301, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(e._id, entry.cid);
|
||||
assertEqual(cn2, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual("12345", entry.data._key);
|
||||
assertEqual(cn + "/test3", entry.data._from);
|
||||
assertEqual(cn + "/test4", entry.data._to);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
assertEqual([ 99, false ], entry.data.test);
|
||||
|
||||
|
@ -1716,6 +1824,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2302, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(e._id, entry.cid);
|
||||
assertEqual(cn2, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual(rev, entry.oldRev);
|
||||
|
||||
|
@ -1772,6 +1881,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2301, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(e._id, entry.cid);
|
||||
assertEqual(cn2, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual("abc", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -1849,6 +1959,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2301, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(e._id, entry.cid);
|
||||
assertEqual(cn2, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual("abc", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2110,6 +2221,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
|
||||
entry = entries.pop();
|
||||
|
@ -2117,6 +2229,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(tid, entry.tid);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual("abc", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2128,6 +2241,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
},
|
||||
|
||||
|
@ -2253,6 +2367,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c1._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(2, entry.collections[0].operations);
|
||||
|
||||
var rev = c1.document("12345")._rev;
|
||||
|
@ -2261,6 +2376,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(tid, entry.tid);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c1._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual("12345", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2272,6 +2388,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(tid, entry.tid);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c1._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual("abc", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2283,6 +2400,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c1._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(2, entry.collections[0].operations);
|
||||
},
|
||||
|
||||
|
@ -2332,8 +2450,10 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(2, entry.collections.length);
|
||||
assertEqual(c1._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
assertEqual(c2._id, entry.collections[1].cid);
|
||||
assertEqual(cn2, entry.collections[1].name);
|
||||
assertEqual(1, entry.collections[1].operations);
|
||||
|
||||
var rev = c1.document("12345")._rev;
|
||||
|
@ -2342,6 +2462,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(tid, entry.tid);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c1._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual("12345", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2353,6 +2474,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(tid, entry.tid);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c2._id, entry.cid);
|
||||
assertEqual(cn2, entry.cname);
|
||||
assertEqual("abc", entry.key);
|
||||
assertEqual("abc", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2364,8 +2486,10 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(2, entry.collections.length);
|
||||
assertEqual(c1._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
assertEqual(c2._id, entry.collections[1].cid);
|
||||
assertEqual(cn2, entry.collections[1].name);
|
||||
assertEqual(1, entry.collections[1].operations);
|
||||
},
|
||||
|
||||
|
@ -2376,8 +2500,6 @@ function ReplicationLoggerSuite () {
|
|||
testLoggerTransactionExcluded1 : function () {
|
||||
var state, tick;
|
||||
var c = db._create(cn);
|
||||
db._drop("_unitfoxx");
|
||||
db._create("_unitfoxx", { isSystem: true });
|
||||
|
||||
replication.logger.start();
|
||||
|
||||
|
@ -2387,15 +2509,15 @@ function ReplicationLoggerSuite () {
|
|||
|
||||
db._executeTransaction({
|
||||
collections: {
|
||||
write: [ cn, "_unitfoxx" ]
|
||||
write: [ cn, "_users" ]
|
||||
},
|
||||
action: function (params) {
|
||||
var c = require("internal").db._collection(params.cn);
|
||||
var foxx = require("internal").db._collection("_unitfoxx");
|
||||
var users = require("internal").db._collection("_users");
|
||||
|
||||
c.save({ "test" : 2, "_key": "12345" });
|
||||
foxx.save({ "_key": "unittests1", "foo": false });
|
||||
foxx.remove("unittests1");
|
||||
users.save({ "_key": "unittests1", "foo": false });
|
||||
users.remove("unittests1");
|
||||
},
|
||||
params: {
|
||||
cn: cn
|
||||
|
@ -2415,6 +2537,7 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
|
||||
var rev = c.document("12345")._rev;
|
||||
|
@ -2423,6 +2546,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(tid, entry.tid);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual("12345", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2434,9 +2558,8 @@ function ReplicationLoggerSuite () {
|
|||
entry = JSON.parse(entry.data);
|
||||
assertEqual(1, entry.collections.length);
|
||||
assertEqual(c._id, entry.collections[0].cid);
|
||||
assertEqual(cn, entry.collections[0].name);
|
||||
assertEqual(1, entry.collections[0].operations);
|
||||
|
||||
db._drop("_unitfoxx");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2479,6 +2602,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual("12345", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
@ -2531,6 +2655,7 @@ function ReplicationLoggerSuite () {
|
|||
assertEqual(2300, entry.type);
|
||||
entry = JSON.parse(entry.data);
|
||||
assertEqual(c._id, entry.cid);
|
||||
assertEqual(cn, entry.cname);
|
||||
assertEqual("12345", entry.key);
|
||||
assertEqual("12345", entry.data._key);
|
||||
assertEqual(rev, entry.data._rev);
|
||||
|
|
Loading…
Reference in New Issue