Commit 5f78cad3 authored by Cédric Le Ninivin's avatar Cédric Le Ninivin

Release version 3.13.0

parent 397381d8
......@@ -7583,6 +7583,9 @@ return new Parser;
i,
value,
result_list;
if (obj === undefined) {
return undefined;
}
if (obj.constructor === Object) {
key_list = Object.keys(obj).sort();
result_list = [];
......@@ -7609,6 +7612,9 @@ return new Parser;
// https://gist.github.com/davoclavo/4424731
function dataURItoBlob(dataURI) {
if (dataURI === 'data:') {
return new Blob();
}
// convert base64 to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]),
// separate out the mime component
......@@ -8442,7 +8448,7 @@ return new Parser;
this._signature_sub_storage = jIO.createJIO({
type: "document",
document_id: this._signature_hash,
sub_storage: spec.local_sub_storage
sub_storage: spec.signature_storage || spec.local_sub_storage
});
this._use_remote_post = spec.use_remote_post || false;
......@@ -8578,18 +8584,7 @@ return new Parser;
});
}
function checkLocalDeletion(queue, destination, id, source) {
var status_hash;
queue
.push(function () {
return context._signature_sub_storage.get(id);
})
.push(function (result) {
status_hash = result.hash;
return destination.get(id)
.push(function (doc) {
var remote_hash = generateHash(stringify(doc));
if (remote_hash === status_hash) {
function propagateDeletion(destination, id) {
return destination.remove(id)
.push(function () {
return context._signature_sub_storage.remove(id);
......@@ -8598,25 +8593,113 @@ return new Parser;
skip_document_dict[id] = null;
});
}
// Modifications on remote side
// Push them locally
return propagateModification(destination, source, doc,
remote_hash, id);
function checkAndPropagate(status_hash, local_hash, doc,
source, destination, id,
conflict_force, conflict_revert,
conflict_ignore,
options) {
return destination.get(id)
.push(function (remote_doc) {
return [remote_doc, generateHash(stringify(remote_doc))];
}, function (error) {
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 404)) {
return [null, null];
}
throw error;
})
.push(function (remote_list) {
var remote_doc = remote_list[0],
remote_hash = remote_list[1];
if (local_hash === remote_hash) {
// Same modifications on both side
if (local_hash === null) {
// Deleted on both side, drop signature
return context._signature_sub_storage.remove(id)
.push(function () {
skip_document_dict[id] = null;
});
}
throw error;
return context._signature_sub_storage.put(id, {
"hash": local_hash
})
.push(function () {
skip_document_dict[id] = null;
});
}
if ((remote_hash === status_hash) || (conflict_force === true)) {
// Modified only locally. No conflict or force
if (local_hash === null) {
// Deleted locally
return propagateDeletion(destination, id);
}
return propagateModification(source, destination, doc,
local_hash, id,
{use_post: ((options.use_post) &&
(remote_hash === null))});
}
// Conflict cases
if (conflict_ignore === true) {
return;
}
if ((conflict_revert === true) || (local_hash === null)) {
// Automatically resolve conflict or force revert
if (remote_hash === null) {
// Deleted remotely
return propagateDeletion(source, id);
}
return propagateModification(
destination,
source,
remote_doc,
remote_hash,
id,
{use_post: ((options.use_revert_post) &&
(local_hash === null))}
);
}
// Minimize conflict if it can be resolved
if (remote_hash === null) {
// Copy remote modification remotely
return propagateModification(source, destination, doc,
local_hash, id,
{use_post: options.use_post});
}
throw new jIO.util.jIOError("Conflict on '" + id + "': " +
stringify(doc || '') + " !== " +
stringify(remote_doc || ''),
409);
});
}
function checkLocalDeletion(queue, destination, id, source,
conflict_force, conflict_revert,
conflict_ignore, options) {
var status_hash;
queue
.push(function () {
return context._signature_sub_storage.get(id);
})
.push(function (result) {
status_hash = result.hash;
return checkAndPropagate(status_hash, null, null,
source, destination, id,
conflict_force, conflict_revert,
conflict_ignore,
options);
});
}
function checkSignatureDifference(queue, source, destination, id,
conflict_force, conflict_ignore,
conflict_force, conflict_revert,
conflict_ignore,
is_creation, is_modification,
getMethod, options) {
queue
......@@ -8625,7 +8708,7 @@ return new Parser;
if (is_creation === true) {
return RSVP.all([
getMethod(id),
{hash: undefined}
{hash: null}
]);
}
if (is_modification === true) {
......@@ -8644,59 +8727,19 @@ return new Parser;
status_hash = result_list[1].hash;
if (local_hash !== status_hash) {
// Local modifications
return destination.get(id)
.push(function (remote_doc) {
var remote_hash = generateHash(stringify(remote_doc));
if (remote_hash !== status_hash) {
// Modifications on both sides
if (local_hash === remote_hash) {
// Same modifications on both side \o/
return context._signature_sub_storage.put(id, {
"hash": local_hash
})
.push(function () {
skip_document_dict[id] = null;
});
}
if (conflict_ignore === true) {
return;
}
if (conflict_force !== true) {
throw new jIO.util.jIOError("Conflict on '" + id + "': " +
stringify(doc) + " !== " +
stringify(remote_doc),
409);
}
}
return propagateModification(source, destination, doc,
local_hash, id);
}, function (error) {
var use_post;
if ((error instanceof jIO.util.jIOError) &&
(error.status_code === 404)) {
if (is_creation) {
// Remote document does not exists, create it following
// provided options
use_post = options.use_post;
} else {
// Remote document has been erased, put it to save
// modification
use_post = false;
}
return propagateModification(source, destination, doc,
local_hash, id,
{use_post: use_post});
}
throw error;
});
return checkAndPropagate(status_hash, local_hash, doc,
source, destination, id,
conflict_force, conflict_revert,
conflict_ignore,
options);
}
});
}
function checkBulkSignatureDifference(queue, source, destination, id_list,
document_status_list, options,
conflict_force, conflict_ignore) {
conflict_force, conflict_revert,
conflict_ignore) {
queue
.push(function () {
return source.bulk(id_list);
......@@ -8717,7 +8760,8 @@ return new Parser;
for (i = 0; i < result_list.length; i += 1) {
checkSignatureDifference(sub_queue, source, destination,
id_list[i].parameter_list[0],
conflict_force, conflict_ignore,
conflict_force, conflict_revert,
conflict_ignore,
document_status_list[i].is_creation,
document_status_list[i].is_modification,
getResult(i), options);
......@@ -8731,6 +8775,9 @@ return new Parser;
if (!options.hasOwnProperty("use_post")) {
options.use_post = false;
}
if (!options.hasOwnProperty("use_revert_post")) {
options.use_revert_post = false;
}
return queue
.push(function () {
return RSVP.all([
......@@ -8780,6 +8827,7 @@ return new Parser;
} else {
checkSignatureDifference(queue, source, destination, key,
options.conflict_force,
options.conflict_revert,
options.conflict_ignore,
is_creation, is_modification,
source.get.bind(source),
......@@ -8792,7 +8840,11 @@ return new Parser;
for (key in signature_dict) {
if (signature_dict.hasOwnProperty(key)) {
if (!local_dict.hasOwnProperty(key)) {
checkLocalDeletion(queue, destination, key, source);
checkLocalDeletion(queue, destination, key, source,
options.conflict_force,
options.conflict_revert,
options.conflict_ignore,
options);
}
}
}
......@@ -8802,6 +8854,7 @@ return new Parser;
document_list, document_status_list,
options,
options.conflict_force,
options.conflict_revert,
options.conflict_ignore);
}
});
......@@ -8853,10 +8906,10 @@ return new Parser;
use_post: context._use_remote_post,
conflict_force: (context._conflict_handling ===
CONFLICT_KEEP_LOCAL),
conflict_ignore: ((context._conflict_handling ===
CONFLICT_CONTINUE) ||
(context._conflict_handling ===
CONFLICT_KEEP_REMOTE)),
conflict_revert: (context._conflict_handling ===
CONFLICT_KEEP_REMOTE),
conflict_ignore: (context._conflict_handling ===
CONFLICT_CONTINUE),
check_modification: context._check_local_modification,
check_creation: context._check_local_creation,
check_deletion: context._check_local_deletion
......@@ -8881,8 +8934,11 @@ return new Parser;
return pushStorage(context._remote_sub_storage,
context._local_sub_storage, {
use_bulk_get: use_bulk_get,
use_revert_post: context._use_remote_post,
conflict_force: (context._conflict_handling ===
CONFLICT_KEEP_REMOTE),
conflict_revert: (context._conflict_handling ===
CONFLICT_KEEP_LOCAL),
conflict_ignore: (context._conflict_handling ===
CONFLICT_CONTINUE),
check_modification: context._check_remote_modification,
......@@ -10872,7 +10928,7 @@ return new Parser;
sub_query,
result_list,
local_roles,
tmp_list = [];
sort_list = [];
if (options.query) {
parsed_query = jIO.QueryFactory.create(options.query);
......@@ -10916,9 +10972,8 @@ return new Parser;
if (options.sort_on) {
for (i = 0; i < options.sort_on.length; i += 1) {
tmp_list.push(JSON.stringify(options.sort_on[i]));
sort_list.push(JSON.stringify(options.sort_on[i]));
}
options.sort_on = tmp_list;
}
return jIO.util.ajax({
......@@ -10929,7 +10984,7 @@ return new Parser;
// XXX Force erp5 to return embedded document
select_list: options.select_list || ["title", "reference"],
limit: options.limit,
sort_on: options.sort_on,
sort_on: sort_list,
local_roles: local_roles
}),
"xhrFields": {
......@@ -11801,9 +11856,11 @@ return new Parser;
*/
/*jslint nomen: true */
/*global indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange*/
/*global indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest,
DOMError, Event*/
(function (indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange) {
(function (indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest,
DOMError) {
"use strict";
// Read only as changing it can lead to data corruption
......@@ -11862,7 +11919,14 @@ return new Parser;
if (request.result) {
request.result.close();
}
if ((error !== undefined) &&
(error.target instanceof IDBOpenDBRequest) &&
(error.target.error instanceof DOMError)) {
reject("Connection to: " + db_name + " failed: " +
error.target.error.message);
} else {
reject(error);
}
};
request.onabort = function () {
......@@ -12223,7 +12287,7 @@ return new Parser;
};
jIO.addStorage("indexeddb", IndexedDBStorage);
}(indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange));
}(indexedDB, jIO, RSVP, Blob, Math, IDBKeyRange, IDBOpenDBRequest, DOMError));
;/*
* Copyright 2015, Nexedi SA
* Released under the LGPL license.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "jio",
"version": "v3.12.0",
"version": "v3.13.0",
"license": "LGPLv3",
"author": "Nexedi SA",
"contributors": [
......
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