Commit acb3274d authored by Romain Courteaud's avatar Romain Courteaud

ReplicateStorage: skip attachment replication if document deletion is skipped

If the document was deleted, user does not want probably to see it reappear identical.
parent cb2eaea6
...@@ -928,6 +928,7 @@ ...@@ -928,6 +928,7 @@
} }
function pushStorage(context, skip_document_dict, function pushStorage(context, skip_document_dict,
skip_deleted_document_dict,
cache, source_key, destination_key, cache, source_key, destination_key,
source, destination, signature_allDocs, options) { source, destination, signature_allDocs, options) {
var argument_list = [], var argument_list = [],
...@@ -1022,10 +1023,10 @@ ...@@ -1022,10 +1023,10 @@
options.operation_amount options.operation_amount
); );
}); });
if (options.check_deletion === true) { for (key in signature_dict) {
for (key in signature_dict) { if (signature_dict.hasOwnProperty(key)) {
if (signature_dict.hasOwnProperty(key)) { if (!local_dict.hasOwnProperty(key)) {
if (!local_dict.hasOwnProperty(key)) { if (options.check_deletion === true) {
argument_list_deletion.push([undefined, argument_list_deletion.push([undefined,
context, context,
skip_document_dict, skip_document_dict,
...@@ -1036,9 +1037,13 @@ ...@@ -1036,9 +1037,13 @@
options.conflict_revert, options.conflict_revert,
options.conflict_ignore, options.conflict_ignore,
options]); options]);
} else {
skip_deleted_document_dict[key] = null;
} }
} }
} }
}
if (argument_list_deletion.length !== 0) {
queue.push(function () { queue.push(function () {
return dispatchQueue( return dispatchQueue(
context, context,
...@@ -1062,6 +1067,7 @@ ...@@ -1062,6 +1067,7 @@
var context = this, var context = this,
argument_list = arguments, argument_list = arguments,
skip_document_dict = {}, skip_document_dict = {},
skip_deleted_document_dict = {},
cache = {}; cache = {};
return new RSVP.Queue() return new RSVP.Queue()
...@@ -1125,6 +1131,7 @@ ...@@ -1125,6 +1131,7 @@
context._check_local_creation || context._check_local_creation ||
context._check_local_deletion) { context._check_local_deletion) {
return pushStorage(context, skip_document_dict, return pushStorage(context, skip_document_dict,
skip_deleted_document_dict,
cache, 'local', 'remote', cache, 'local', 'remote',
context._local_sub_storage, context._local_sub_storage,
context._remote_sub_storage, context._remote_sub_storage,
...@@ -1154,6 +1161,7 @@ ...@@ -1154,6 +1161,7 @@
context._check_remote_creation || context._check_remote_creation ||
context._check_remote_deletion) { context._check_remote_deletion) {
return pushStorage(context, skip_document_dict, return pushStorage(context, skip_document_dict,
skip_deleted_document_dict,
cache, 'remote', 'local', cache, 'remote', 'local',
context._remote_sub_storage, context._remote_sub_storage,
context._local_sub_storage, context._local_sub_storage,
...@@ -1186,12 +1194,19 @@ ...@@ -1186,12 +1194,19 @@
.push(function (result) { .push(function (result) {
var i, var i,
local_argument_list = [], local_argument_list = [],
id,
len = result.data.total_rows; len = result.data.total_rows;
for (i = 0; i < len; i += 1) { for (i = 0; i < len; i += 1) {
local_argument_list.push( id = result.data.rows[i].id;
[undefined, context, result.data.rows[i].id] // Do not synchronize attachment if one version of the document
); // is deleted but not pushed to the other storage
if (!skip_deleted_document_dict.hasOwnProperty(id) ||
skip_document_dict.hasOwnProperty(id)) {
local_argument_list.push(
[undefined, context, id]
);
}
} }
return dispatchQueue( return dispatchQueue(
context, context,
......
...@@ -3649,5 +3649,343 @@ ...@@ -3649,5 +3649,343 @@
}); });
}); });
test("attachment skipped when local document deletion skipped", function () {
stop();
expect(18);
var id,
context = this,
blob = new Blob(['a']),
blob2 = new Blob(['b']);
this.jio = jIO.createJIO({
type: "replicate",
check_local_deletion: false,
check_local_attachment_modification: true,
check_local_attachment_creation: true,
check_local_attachment_deletion: true,
check_remote_attachment_modification: true,
check_remote_attachment_creation: true,
check_remote_attachment_deletion: true,
local_sub_storage: {
type: "uuid",
sub_storage: {
type: "memory"
}
},
remote_sub_storage: {
type: "uuid",
sub_storage: {
type: "memory"
}
}
});
context.jio.post({"title": "foo"})
.then(function (result) {
id = result;
return RSVP.all([
context.jio.putAttachment(id, "foo", blob),
context.jio.putAttachment(id, "foomod", blob),
context.jio.putAttachment(id, "foodel", blob)
]);
})
.then(function () {
return context.jio.repair();
})
.then(function () {
return RSVP.all([
context.jio.remove(id),
context.jio.__storage._remote_sub_storage
.putAttachment(id, "foomod", blob2),
context.jio.__storage._remote_sub_storage
.putAttachment(id, "foocre", blob),
context.jio.__storage._remote_sub_storage
.removeAttachment(id, "foodel")
]);
})
.then(function () {
return context.jio.repair();
})
.then(function () {
ok(true, 'second repair success');
// local document still deleted
return context.jio.get(id);
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 404);
equal(error.message, "Cannot find document: " + id);
// document signature untouched
return context.jio.__storage._signature_sub_storage
.get(id);
})
.then(function (result) {
deepEqual(result, {hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"});
// remote document untouched
return context.jio.__storage._remote_sub_storage.get(id);
})
.then(function (result) {
deepEqual(result, {"title": "foo"});
// frozen attachment untouched
return context.jio.__storage._remote_sub_storage.getAttachment(
id,
"foo",
{format: "text"}
);
})
.then(function (result) {
equal(result, "a");
// frozen attachment signature not created
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foo", {format: "json"});
})
.then(function (result) {
deepEqual(result, {hash: "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"});
// created attachment untouched
return context.jio.__storage._remote_sub_storage.getAttachment(
id,
"foocre",
{format: "text"}
);
})
.then(function (result) {
equal(result, "a");
// created attachment signature not created
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foocre", {format: "json"});
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 404);
var error_message = "Cannot find attachment: " +
"_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
"jio_attachment/";
equal(
error.message.substring(0, error_message.length),
error_message
);
// modified attachment untouched
return context.jio.__storage._remote_sub_storage.getAttachment(
id,
"foomod",
{format: "text"}
);
})
.then(function (result) {
equal(result, "b");
// modified attachment signature not created
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foomod", {format: "json"});
})
.then(function (result) {
deepEqual(result, {hash: "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"});
// deleted attachment untouched
return context.jio.__storage._remote_sub_storage.getAttachment(
id,
"foodel",
{format: "text"}
);
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 404);
var error_message = "Cannot find attachment: " +
id + " , foodel";
equal(
error.message.substring(0, error_message.length),
error_message
);
// deleted attachment signature untouched
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foodel", {format: "json"});
})
.then(function (result) {
deepEqual(result, {hash: "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("attachment skipped when remot document deletion skipped", function () {
stop();
expect(18);
var id,
context = this,
blob = new Blob(['a']),
blob2 = new Blob(['b']);
this.jio = jIO.createJIO({
type: "replicate",
check_remote_deletion: false,
check_local_attachment_modification: true,
check_local_attachment_creation: true,
check_local_attachment_deletion: true,
check_remote_attachment_modification: true,
check_remote_attachment_creation: true,
check_remote_attachment_deletion: true,
local_sub_storage: {
type: "uuid",
sub_storage: {
type: "memory"
}
},
remote_sub_storage: {
type: "uuid",
sub_storage: {
type: "memory"
}
}
});
context.jio.post({"title": "foo"})
.then(function (result) {
id = result;
return RSVP.all([
context.jio.putAttachment(id, "foo", blob),
context.jio.putAttachment(id, "foomod", blob),
context.jio.putAttachment(id, "foodel", blob)
]);
})
.then(function () {
return context.jio.repair();
})
.then(function () {
return RSVP.all([
context.jio.__storage._remote_sub_storage.remove(id),
context.jio.putAttachment(id, "foomod", blob2),
context.jio.putAttachment(id, "foocre", blob),
context.jio.removeAttachment(id, "foodel")
]);
})
.then(function () {
return context.jio.repair();
})
.then(function () {
ok(true, 'second repair success');
// remote document still deleted
return context.jio.__storage._remote_sub_storage.get(id);
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 404);
equal(error.message, "Cannot find document: " + id);
// document signature untouched
return context.jio.__storage._signature_sub_storage
.get(id);
})
.then(function (result) {
deepEqual(result, {hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"});
// local document untouched
return context.jio.get(id);
})
.then(function (result) {
deepEqual(result, {"title": "foo"});
// frozen attachment untouched
return context.jio.getAttachment(
id,
"foo",
{format: "text"}
);
})
.then(function (result) {
equal(result, "a");
// frozen attachment signature not created
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foo", {format: "json"});
})
.then(function (result) {
deepEqual(result, {hash: "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"});
// created attachment untouched
return context.jio.getAttachment(
id,
"foocre",
{format: "text"}
);
})
.then(function (result) {
equal(result, "a");
// created attachment signature not created
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foocre", {format: "json"});
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 404);
var error_message = "Cannot find attachment: " +
"_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
"jio_attachment/";
equal(
error.message.substring(0, error_message.length),
error_message
);
// modified attachment untouched
return context.jio.getAttachment(
id,
"foomod",
{format: "text"}
);
})
.then(function (result) {
equal(result, "b");
// modified attachment signature not created
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foomod", {format: "json"});
})
.then(function (result) {
deepEqual(result, {hash: "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"});
// deleted attachment untouched
return context.jio.getAttachment(
id,
"foodel",
{format: "text"}
);
})
.fail(function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 404);
var error_message = "Cannot find attachment: " +
id + " , foodel";
equal(
error.message.substring(0, error_message.length),
error_message
);
// deleted attachment signature untouched
return context.jio.__storage._signature_sub_storage
.getAttachment(id, "foodel", {format: "json"});
})
.then(function (result) {
deepEqual(result, {hash: "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(jIO, QUnit, Blob, RSVP)); }(jIO, QUnit, Blob, RSVP));
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment