Commit f563c978 authored by Tristan Cavelier's avatar Tristan Cavelier

replicaterevisionstorage amd compatible now

parent 286266f6
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global jIO: true */
/*global jIO, define */
/**
* JIO Replicate Revision Storage.
* It manages storages that manage revisions and conflicts.
......@@ -12,666 +13,680 @@
* ]
* }
*/
jIO.addStorageType('replicaterevision', function (spec, my) {
// define([module_name], [dependencies], module);
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO);
}(['jio'], function (jIO) {
"use strict";
var that, priv = {};
spec = spec || {};
that = my.basicStorage(spec, my);
jIO.addStorageType('replicaterevision', function (spec, my) {
var that, priv = {};
spec = spec || {};
that = my.basicStorage(spec, my);
priv.storage_list_key = "storage_list";
priv.storage_list = spec[priv.storage_list_key];
priv.emptyFunction = function () {};
priv.storage_list_key = "storage_list";
priv.storage_list = spec[priv.storage_list_key];
priv.emptyFunction = function () {};
that.specToStore = function () {
var o = {};
o[priv.storage_list_key] = priv.storage_list;
return o;
};
that.specToStore = function () {
var o = {};
o[priv.storage_list_key] = priv.storage_list;
return o;
};
/**
* Generate a new uuid
* @method generateUuid
* @return {string} The new uuid
*/
priv.generateUuid = function () {
var S4 = function () {
var i, string = Math.floor(
Math.random() * 0x10000 /* 65536 */
).toString(16);
for (i = string.length; i < 4; i += 1) {
string = "0" + string;
}
return string;
/**
* Generate a new uuid
* @method generateUuid
* @return {string} The new uuid
*/
priv.generateUuid = function () {
var S4 = function () {
var i, string = Math.floor(
Math.random() * 0x10000 /* 65536 */
).toString(16);
for (i = string.length; i < 4; i += 1) {
string = "0" + string;
}
return string;
};
return S4() + S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + S4() + S4();
};
return S4() + S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + "-" +
S4() + S4() + S4();
};
/**
* Create an array containing dictionnary keys
* @method dictKeys2Array
* @param {object} dict The object to convert
* @return {array} The array of keys
*/
priv.dictKeys2Array = function (dict) {
var k, newlist = [];
for (k in dict) {
if (dict.hasOwnProperty(k)) {
newlist.push(k);
/**
* Create an array containing dictionnary keys
* @method dictKeys2Array
* @param {object} dict The object to convert
* @return {array} The array of keys
*/
priv.dictKeys2Array = function (dict) {
var k, newlist = [];
for (k in dict) {
if (dict.hasOwnProperty(k)) {
newlist.push(k);
}
}
}
return newlist;
};
return newlist;
};
/**
* Checks a revision format
* @method checkRevisionFormat
* @param {string} revision The revision string
* @return {boolean} True if ok, else false
*/
priv.checkRevisionFormat = function (revision) {
return (/^[0-9]+-[0-9a-zA-Z_]+$/.test(revision));
};
/**
* Checks a revision format
* @method checkRevisionFormat
* @param {string} revision The revision string
* @return {boolean} True if ok, else false
*/
priv.checkRevisionFormat = function (revision) {
return (/^[0-9]+-[0-9a-zA-Z_]+$/.test(revision));
};
/**
* Clones an object in deep (without functions)
* @method clone
* @param {any} object The object to clone
* @return {any} The cloned object
*/
priv.clone = function (object) {
var tmp = JSON.stringify(object);
if (tmp === undefined) {
return undefined;
}
return JSON.parse(tmp);
};
/**
* Clones an object in deep (without functions)
* @method clone
* @param {any} object The object to clone
* @return {any} The cloned object
*/
priv.clone = function (object) {
var tmp = JSON.stringify(object);
if (tmp === undefined) {
return undefined;
}
return JSON.parse(tmp);
};
/**
* Like addJob but also return the method and the index of the storage
* @method send
* @param {string} method The request method
* @param {number} index The storage index
* @param {object} doc The document object
* @param {object} option The request object
* @param {function} callback The callback. Parameters:
* - {string} The request method
* - {number} The storage index
* - {object} The error object
* - {object} The response object
*/
priv.send = function (method, index, doc, option, callback) {
var wrapped_callback_success, wrapped_callback_error;
callback = callback || priv.emptyFunction;
wrapped_callback_success = function (response) {
callback(method, index, undefined, response);
/**
* Like addJob but also return the method and the index of the storage
* @method send
* @param {string} method The request method
* @param {number} index The storage index
* @param {object} doc The document object
* @param {object} option The request object
* @param {function} callback The callback. Parameters:
* - {string} The request method
* - {number} The storage index
* - {object} The error object
* - {object} The response object
*/
priv.send = function (method, index, doc, option, callback) {
var wrapped_callback_success, wrapped_callback_error;
callback = callback || priv.emptyFunction;
wrapped_callback_success = function (response) {
callback(method, index, undefined, response);
};
wrapped_callback_error = function (err) {
callback(method, index, err, undefined);
};
that.addJob(
method,
priv.storage_list[index],
doc,
option,
wrapped_callback_success,
wrapped_callback_error
);
};
wrapped_callback_error = function (err) {
callback(method, index, err, undefined);
/**
* Use "send" method to all sub storages.
* Calling "callback" for each storage response.
* @method sendToAll
* @param {string} method The request method
* @param {object} doc The document object
* @param {object} option The request option
* @param {function} callback The callback. Parameters:
* - {string} The request method
* - {number} The storage index
* - {object} The error object
* - {object} The response object
*/
priv.sendToAll = function (method, doc, option, callback) {
var i;
for (i = 0; i < priv.storage_list.length; i += 1) {
priv.send(method, i, doc, option, callback);
}
};
that.addJob(
/**
* Use "send" method to all sub storages.
* Calling "callback" only with the first response
* @method sendToAllFastestResponseOnly
* @param {string} method The request method
* @param {object} doc The document object
* @param {object} option The request option
* @param {function} callback The callback. Parameters:
* - {string} The request method
* - {object} The error object
* - {object} The response object
*/
priv.sendToAllFastestResponseOnly = function (
method,
priv.storage_list[index],
doc,
option,
wrapped_callback_success,
wrapped_callback_error
);
};
/**
* Use "send" method to all sub storages.
* Calling "callback" for each storage response.
* @method sendToAll
* @param {string} method The request method
* @param {object} doc The document object
* @param {object} option The request option
* @param {function} callback The callback. Parameters:
* - {string} The request method
* - {number} The storage index
* - {object} The error object
* - {object} The response object
*/
priv.sendToAll = function (method, doc, option, callback) {
var i;
for (i = 0; i < priv.storage_list.length; i += 1) {
priv.send(method, i, doc, option, callback);
}
};
/**
* Use "send" method to all sub storages.
* Calling "callback" only with the first response
* @method sendToAllFastestResponseOnly
* @param {string} method The request method
* @param {object} doc The document object
* @param {object} option The request option
* @param {function} callback The callback. Parameters:
* - {string} The request method
* - {object} The error object
* - {object} The response object
*/
priv.sendToAllFastestResponseOnly = function (method, doc, option, callback) {
var i, callbackWrapper, error_count, last_error;
error_count = 0;
callbackWrapper = function (method, index, err, response) {
if (err) {
error_count += 1;
last_error = err;
if (error_count === priv.storage_list.length) {
return callback(method, err, response);
callback
) {
var i, callbackWrapper, error_count, last_error;
error_count = 0;
callbackWrapper = function (method, index, err, response) {
if (err) {
error_count += 1;
last_error = err;
if (error_count === priv.storage_list.length) {
return callback(method, err, response);
}
}
callback(method, err, response);
};
for (i = 0; i < priv.storage_list.length; i += 1) {
priv.send(method, i, doc, option, callbackWrapper);
}
callback(method, err, response);
};
for (i = 0; i < priv.storage_list.length; i += 1) {
priv.send(method, i, doc, option, callbackWrapper);
}
};
/**
* Use "sendToAll" method, calling "callback" at the last response with
* the response list
* @method sendToAllGetResponseList
* @param {string} method The request method
* @param {object} doc The document object
* @param {object} option The request option
* @return {function} callback The callback. Parameters:
* - {string} The request method
* - {object} The error object
* - {object} The response object
*/
priv.sendToAllGetResponseList = function (method, doc, option, callback) {
var wrapper, callback_count = 0, response_list = [], error_list = [];
response_list.length = priv.storage_list.length;
wrapper = function (method, index, err, response) {
error_list[index] = err;
response_list[index] = response;
callback_count += 1;
if (callback_count === priv.storage_list.length) {
callback(error_list, response_list);
}
/**
* Use "sendToAll" method, calling "callback" at the last response with
* the response list
* @method sendToAllGetResponseList
* @param {string} method The request method
* @param {object} doc The document object
* @param {object} option The request option
* @return {function} callback The callback. Parameters:
* - {string} The request method
* - {object} The error object
* - {object} The response object
*/
priv.sendToAllGetResponseList = function (method, doc, option, callback) {
var wrapper, callback_count = 0, response_list = [], error_list = [];
response_list.length = priv.storage_list.length;
wrapper = function (method, index, err, response) {
error_list[index] = err;
response_list[index] = response;
callback_count += 1;
if (callback_count === priv.storage_list.length) {
callback(error_list, response_list);
}
};
priv.sendToAll(method, doc, option, wrapper);
};
priv.sendToAll(method, doc, option, wrapper);
};
/**
* Checks if the sub storage are identical
* @method check
* @param {object} command The JIO command
*/
that.check = function (command) {
function callback(err, response) {
if (err) {
return that.error(err);
}
that.success(response);
}
priv.check(
command.cloneDoc(),
command.cloneOption(),
callback
);
};
/**
* Repair the sub storages to make them identical
* @method repair
* @param {object} command The JIO command
*/
that.repair = function (command) {
function callback(err, response) {
if (err) {
return that.error(err);
/**
* Checks if the sub storage are identical
* @method check
* @param {object} command The JIO command
*/
that.check = function (command) {
function callback(err, response) {
if (err) {
return that.error(err);
}
that.success(response);
}
that.success(response);
}
priv.repair(
command.cloneDoc(),
command.cloneOption(),
true,
callback
);
};
priv.check = function (doc, option, success, error) {
priv.repair(doc, option, false, success, error);
};
priv.check(
command.cloneDoc(),
command.cloneOption(),
callback
);
};
priv.repair = function (doc, option, repair, callback) {
var functions = {};
callback = callback || priv.emptyFunction;
option = option || {};
functions.begin = function () {
// };
// functions.repairAllSubStorages = function () {
var i;
for (i = 0; i < priv.storage_list.length; i += 1) {
priv.send(
repair ? "repair" : "check",
i,
doc,
option,
functions.repairAllSubStoragesCallback
);
/**
* Repair the sub storages to make them identical
* @method repair
* @param {object} command The JIO command
*/
that.repair = function (command) {
function callback(err, response) {
if (err) {
return that.error(err);
}
that.success(response);
}
priv.repair(
command.cloneDoc(),
command.cloneOption(),
true,
callback
);
};
functions.repair_sub_storages_count = 0;
functions.repairAllSubStoragesCallback = function (method,
index, err, response) {
if (err) {
return that.error(err);
}
functions.repair_sub_storages_count += 1;
if (functions.repair_sub_storages_count === priv.storage_list.length) {
functions.getAllDocuments(functions.newParam(
doc,
option,
repair
));
}
priv.check = function (doc, option, success, error) {
priv.repair(doc, option, false, success, error);
};
functions.newParam = function (doc, option, repair) {
var param = {
"doc": doc, // the document to repair
"option": option,
"repair": repair,
"responses": {
"count": 0,
"list": [
// 0: response0
// 1: response1
// 2: response2
],
"stats": {
// responseA: [0, 1]
// responseB: [2]
priv.repair = function (doc, option, repair, callback) {
var functions = {};
callback = callback || priv.emptyFunction;
option = option || {};
functions.begin = function () {
// };
// functions.repairAllSubStorages = function () {
var i;
for (i = 0; i < priv.storage_list.length; i += 1) {
priv.send(
repair ? "repair" : "check",
i,
doc,
option,
functions.repairAllSubStoragesCallback
);
}
};
functions.repair_sub_storages_count = 0;
functions.repairAllSubStoragesCallback = function (method,
index, err, response) {
if (err) {
return that.error(err);
}
functions.repair_sub_storages_count += 1;
if (functions.repair_sub_storages_count === priv.storage_list.length) {
functions.getAllDocuments(functions.newParam(
doc,
option,
repair
));
}
};
functions.newParam = function (doc, option, repair) {
var param = {
"doc": doc, // the document to repair
"option": option,
"repair": repair,
"responses": {
"count": 0,
"list": [
// 0: response0
// 1: response1
// 2: response2
],
"stats": {
// responseA: [0, 1]
// responseB: [2]
},
"stats_items": [
// 0: [responseA, [0, 1]]
// 1: [responseB, [2]]
],
"attachments": {
// attachmentA : {_id: attachmentA, _revs_info, _mimetype: ..}
// attachmentB : {_id: attachmentB, _revs_info, _mimetype: ..}
}
},
"stats_items": [
// 0: [responseA, [0, 1]]
// 1: [responseB, [2]]
],
"attachments": {
// attachmentA : {_id: attachmentA, _revs_info, _mimetype: ..}
// attachmentB : {_id: attachmentB, _revs_info, _mimetype: ..}
"conflicts": {
// revC: true
// revD: true
},
"deal_result_state": "ok",
"my_rev": undefined
};
param.responses.list.length = priv.storage_list.length;
return param;
};
functions.getAllDocuments = function (param) {
var i, doc = priv.clone(param.doc), option = priv.clone(param.option);
option.conflicts = true;
option.revs = true;
option.revs_info = true;
for (i = 0; i < priv.storage_list.length; i += 1) {
// if the document is not loaded
priv.send("get", i, doc, option, functions.dealResults(param));
}
functions.finished_count += 1;
};
functions.dealResults = function (param) {
return function (method, index, err, response) {
var response_object = {};
if (param.deal_result_state !== "ok") {
// deal result is in a wrong state, exit
return;
}
if (err) {
if (err.status !== 404) {
// get document failed, exit
param.deal_result_state = "error";
callback({
"status": 40,
"statusText": "Check Failed",
"error": "check_failed",
"message": "An error occured on the sub storage",
"reason": err.reason
}, undefined);
return;
}
}
},
"conflicts": {
// revC: true
// revD: true
},
"deal_result_state": "ok",
"my_rev": undefined
// success to get the document
// add the response in memory
param.responses.count += 1;
param.responses.list[index] = response;
// add the conflicting revision for other synchronizations
functions.addConflicts(param, (response || {})._conflicts);
if (param.responses.count !== param.responses.list.length) {
// this is not the last response, wait for the next response
return;
}
// this is now the last response
functions.makeResponsesStats(param.responses);
if (param.responses.stats_items.length === 1) {
// the responses are equals!
response_object.ok = true;
response_object.id = param.doc._id;
if (doc._rev) {
response_object.rev = doc._rev;
// "rev": (typeof param.responses.list[0] === "object" ?
// param.responses.list[0]._rev : undefined)
}
callback(undefined, response_object);
return;
}
// the responses are different
if (param.repair === false) {
// do not repair
callback({
"status": 41,
"statusText": "Check Not Ok",
"error": "check_not_ok",
"message": "Some documents are different in the sub storages",
"reason": "Storage contents differ"
}, undefined);
return;
}
// repair
functions.getAttachments(param);
};
};
param.responses.list.length = priv.storage_list.length;
return param;
};
functions.getAllDocuments = function (param) {
var i, doc = priv.clone(param.doc), option = priv.clone(param.option);
option.conflicts = true;
option.revs = true;
option.revs_info = true;
for (i = 0; i < priv.storage_list.length; i += 1) {
// if the document is not loaded
priv.send("get", i, doc, option, functions.dealResults(param));
}
functions.finished_count += 1;
};
functions.dealResults = function (param) {
return function (method, index, err, response) {
var response_object = {};
if (param.deal_result_state !== "ok") {
// deal result is in a wrong state, exit
return;
functions.addConflicts = function (param, list) {
var i;
list = list || [];
for (i = 0; i < list.length; i += 1) {
param.conflicts[list[i]] = true;
}
if (err) {
if (err.status !== 404) {
// get document failed, exit
param.deal_result_state = "error";
};
functions.makeResponsesStats = function (responses) {
var i, str_response;
for (i = 0; i < responses.count; i += 1) {
str_response = JSON.stringify(responses.list[i]);
if (responses.stats[str_response] === undefined) {
responses.stats[str_response] = [];
responses.stats_items.push([
str_response,
responses.stats[str_response]
]);
}
responses.stats[str_response].push(i);
}
};
functions.getAttachments = function (param) {
var response, parsed_response, attachment;
for (response in param.responses.stats) {
if (param.responses.stats.hasOwnProperty(response)) {
parsed_response = JSON.parse(response);
for (attachment in parsed_response._attachments) {
if ((parsed_response._attachments).hasOwnProperty(attachment)) {
functions.get_attachment_count += 1;
priv.send(
"getAttachment",
param.responses.stats[response][0],
{
"_id": param.doc._id,
"_attachment": attachment,
"_rev": JSON.parse(response)._rev
},
param.option,
functions.getAttachmentsCallback(
param,
attachment,
param.responses.stats[response]
)
);
}
}
}
}
};
functions.get_attachment_count = 0;
functions.getAttachmentsCallback = function (
param,
attachment_id,
index_list
) {
return function (method, index, err, response) {
if (err) {
callback({
"status": 40,
"statusText": "Check Failed",
"error": "check_failed",
"message": "An error occured on the sub storage",
"message": "Unable to retreive attachments",
"reason": err.reason
}, undefined);
return;
}
}
// success to get the document
// add the response in memory
param.responses.count += 1;
param.responses.list[index] = response;
// add the conflicting revision for other synchronizations
functions.addConflicts(param, (response || {})._conflicts);
if (param.responses.count !== param.responses.list.length) {
// this is not the last response, wait for the next response
return;
}
// this is now the last response
functions.makeResponsesStats(param.responses);
if (param.responses.stats_items.length === 1) {
// the responses are equals!
response_object.ok = true;
response_object.id = param.doc._id;
if (doc._rev) {
response_object.rev = doc._rev;
// "rev": (typeof param.responses.list[0] === "object" ?
// param.responses.list[0]._rev : undefined)
functions.get_attachment_count -= 1;
param.responses.attachments[attachment_id] = response;
if (functions.get_attachment_count === 0) {
functions.synchronizeAllSubStorage(param);
if (param.option.synchronize_conflicts !== false) {
functions.synchronizeConflicts(param);
}
}
callback(undefined, response_object);
return;
}
// the responses are different
if (param.repair === false) {
// do not repair
callback({
"status": 41,
"statusText": "Check Not Ok",
"error": "check_not_ok",
"message": "Some documents are different in the sub storages",
"reason": "Storage contents differ"
}, undefined);
return;
}
// repair
functions.getAttachments(param);
};
};
};
functions.addConflicts = function (param, list) {
var i;
list = list || [];
for (i = 0; i < list.length; i += 1) {
param.conflicts[list[i]] = true;
}
};
functions.makeResponsesStats = function (responses) {
var i, str_response;
for (i = 0; i < responses.count; i += 1) {
str_response = JSON.stringify(responses.list[i]);
if (responses.stats[str_response] === undefined) {
responses.stats[str_response] = [];
responses.stats_items.push([
str_response,
responses.stats[str_response]
]);
}
responses.stats[str_response].push(i);
}
};
functions.getAttachments = function (param) {
var response, parsed_response, attachment;
for (response in param.responses.stats) {
if (param.responses.stats.hasOwnProperty(response)) {
parsed_response = JSON.parse(response);
for (attachment in parsed_response._attachments) {
if ((parsed_response._attachments).hasOwnProperty(attachment)) {
functions.get_attachment_count += 1;
priv.send(
"getAttachment",
param.responses.stats[response][0],
{
"_id": param.doc._id,
"_attachment": attachment,
"_rev": JSON.parse(response)._rev
},
param.option,
functions.getAttachmentsCallback(
param,
attachment,
param.responses.stats[response]
)
functions.synchronizeAllSubStorage = function (param) {
var i, j, len = param.responses.stats_items.length;
for (i = 0; i < len; i += 1) {
// browsing responses
for (j = 0; j < len; j += 1) {
// browsing storage list
if (i !== j) {
functions.synchronizeResponseToSubStorage(
param,
param.responses.stats_items[i][0],
param.responses.stats_items[j][1]
);
}
}
}
}
};
functions.get_attachment_count = 0;
functions.getAttachmentsCallback = function (
param,
attachment_id,
index_list
) {
return function (method, index, err, response) {
if (err) {
callback({
"status": 40,
"statusText": "Check Failed",
"error": "check_failed",
"message": "Unable to retreive attachments",
"reason": err.reason
}, undefined);
functions.finished_count -= 1;
};
functions.synchronizeResponseToSubStorage = function (
param,
response,
storage_list
) {
var i, new_doc, attachment_to_put = [];
if (response === undefined) {
// no response to sync
return;
}
functions.get_attachment_count -= 1;
param.responses.attachments[attachment_id] = response;
if (functions.get_attachment_count === 0) {
functions.synchronizeAllSubStorage(param);
if (param.option.synchronize_conflicts !== false) {
functions.synchronizeConflicts(param);
}
}
};
};
functions.synchronizeAllSubStorage = function (param) {
var i, j, len = param.responses.stats_items.length;
for (i = 0; i < len; i += 1) {
// browsing responses
for (j = 0; j < len; j += 1) {
// browsing storage list
if (i !== j) {
functions.synchronizeResponseToSubStorage(
param,
param.responses.stats_items[i][0],
param.responses.stats_items[j][1]
);
new_doc = JSON.parse(response);
new_doc._revs = new_doc._revisions;
delete new_doc._rev;
delete new_doc._revisions;
delete new_doc._conflicts;
for (i in new_doc._attachments) {
if (new_doc._attachments.hasOwnProperty(i)) {
attachment_to_put.push({
"_id": i,
"_mimetype": new_doc._attachments[i].content_type,
"_revs_info": new_doc._revs_info
});
}
}
}
functions.finished_count -= 1;
};
functions.synchronizeResponseToSubStorage = function (
param,
response,
storage_list
) {
var i, new_doc, attachment_to_put = [];
if (response === undefined) {
// no response to sync
return;
}
new_doc = JSON.parse(response);
new_doc._revs = new_doc._revisions;
delete new_doc._rev;
delete new_doc._revisions;
delete new_doc._conflicts;
for (i in new_doc._attachments) {
if (new_doc._attachments.hasOwnProperty(i)) {
attachment_to_put.push({
"_id": i,
"_mimetype": new_doc._attachments[i].content_type,
"_revs_info": new_doc._revs_info
});
}
}
for (i = 0; i < storage_list.length; i += 1) {
functions.finished_count += attachment_to_put.length || 1;
priv.send(
"put",
storage_list[i],
new_doc,
param.option,
functions.putAttachments(param, attachment_to_put)
);
}
functions.finished_count += 1;
functions.finished();
};
functions.synchronizeConflicts = function (param) {
var rev, new_doc, new_option;
new_option = priv.clone(param.option);
new_option.synchronize_conflict = false;
for (rev in param.conflicts) {
if (param.conflicts.hasOwnProperty(rev)) {
new_doc = priv.clone(param.doc);
new_doc._rev = rev;
// no need to synchronize all the conflicts again, do it once
functions.getAllDocuments(functions.newParam(
new_doc,
new_option,
param.repair
));
}
}
};
functions.putAttachments = function (param, attachment_to_put) {
return function (method, index, err, response) {
var i, attachment;
if (err) {
return callback({
"status": 40,
"statusText": "Check Failed",
"error": "check_failed",
"message": "Unable to copy attachments",
"reason": err.reason
}, undefined);
}
for (i = 0; i < attachment_to_put.length; i += 1) {
attachment = {
"_id": param.doc._id,
"_attachment": attachment_to_put[i]._id,
"_mimetype": attachment_to_put[i]._mimetype,
"_revs_info": attachment_to_put[i]._revs_info,
// "_revs_info": param.responses.list[index]._revs_info,
"_data": param.responses.attachments[attachment_to_put[i]._id]
};
for (i = 0; i < storage_list.length; i += 1) {
functions.finished_count += attachment_to_put.length || 1;
priv.send(
"putAttachment",
index,
attachment,
option,
functions.putAttachmentCallback(param)
"put",
storage_list[i],
new_doc,
param.option,
functions.putAttachments(param, attachment_to_put)
);
}
if (attachment_to_put.length === 0) {
functions.finished();
}
functions.finished_count += 1;
functions.finished();
};
};
functions.putAttachmentCallback = function (param) {
return function (method, index, err, response) {
if (err) {
return callback(err, undefined);
functions.synchronizeConflicts = function (param) {
var rev, new_doc, new_option;
new_option = priv.clone(param.option);
new_option.synchronize_conflict = false;
for (rev in param.conflicts) {
if (param.conflicts.hasOwnProperty(rev)) {
new_doc = priv.clone(param.doc);
new_doc._rev = rev;
// no need to synchronize all the conflicts again, do it once
functions.getAllDocuments(functions.newParam(
new_doc,
new_option,
param.repair
));
}
}
functions.finished();
};
};
functions.finished_count = 0;
functions.finished = function () {
var response_object = {};
functions.finished_count -= 1;
if (functions.finished_count === 0) {
response_object.ok = true;
response_object.id = doc._id;
if (doc._rev) {
response_object.rev = doc._rev;
functions.putAttachments = function (param, attachment_to_put) {
return function (method, index, err, response) {
var i, attachment;
if (err) {
return callback({
"status": 40,
"statusText": "Check Failed",
"error": "check_failed",
"message": "Unable to copy attachments",
"reason": err.reason
}, undefined);
}
for (i = 0; i < attachment_to_put.length; i += 1) {
attachment = {
"_id": param.doc._id,
"_attachment": attachment_to_put[i]._id,
"_mimetype": attachment_to_put[i]._mimetype,
"_revs_info": attachment_to_put[i]._revs_info,
// "_revs_info": param.responses.list[index]._revs_info,
"_data": param.responses.attachments[attachment_to_put[i]._id]
};
priv.send(
"putAttachment",
index,
attachment,
option,
functions.putAttachmentCallback(param)
);
}
if (attachment_to_put.length === 0) {
functions.finished();
}
};
};
functions.putAttachmentCallback = function (param) {
return function (method, index, err, response) {
if (err) {
return callback(err, undefined);
}
functions.finished();
};
};
functions.finished_count = 0;
functions.finished = function () {
var response_object = {};
functions.finished_count -= 1;
if (functions.finished_count === 0) {
response_object.ok = true;
response_object.id = doc._id;
if (doc._rev) {
response_object.rev = doc._rev;
}
callback(undefined, response_object);
}
callback(undefined, response_object);
}
};
functions.begin();
};
functions.begin();
};
/**
* The generic method to use
* @method genericRequest
* @param {object} command The JIO command
* @param {string} method The method to use
*/
that.genericRequest = function (command, method) {
var doc = command.cloneDoc();
doc._id = doc._id || priv.generateUuid();
priv.sendToAllFastestResponseOnly(
method,
doc,
command.cloneOption(),
function (method, err, response) {
if (err) {
return that.error(err);
/**
* The generic method to use
* @method genericRequest
* @param {object} command The JIO command
* @param {string} method The method to use
*/
that.genericRequest = function (command, method) {
var doc = command.cloneDoc();
doc._id = doc._id || priv.generateUuid();
priv.sendToAllFastestResponseOnly(
method,
doc,
command.cloneOption(),
function (method, err, response) {
if (err) {
return that.error(err);
}
that.success(response);
}
that.success(response);
}
);
};
);
};
/**
* Post the document metadata to all sub storages
* @method post
* @param {object} command The JIO command
*/
that.post = function (command) {
that.genericRequest(command, "put");
};
/**
* Post the document metadata to all sub storages
* @method post
* @param {object} command The JIO command
*/
that.post = function (command) {
that.genericRequest(command, "put");
};
/**
* Put the document metadata to all sub storages
* @method put
* @param {object} command The JIO command
*/
that.put = function (command) {
that.genericRequest(command, "post");
};
/**
* Put the document metadata to all sub storages
* @method put
* @param {object} command The JIO command
*/
that.put = function (command) {
that.genericRequest(command, "post");
};
/**
* Put an attachment to a document to all sub storages
* @method putAttachment
* @param {object} command The JIO command
*/
that.putAttachment = function (command) {
that.genericRequest(command, "putAttachment");
};
/**
* Put an attachment to a document to all sub storages
* @method putAttachment
* @param {object} command The JIO command
*/
that.putAttachment = function (command) {
that.genericRequest(command, "putAttachment");
};
/**
* Get the document from all sub storages, get the fastest.
* @method get
* @param {object} command The JIO command
*/
that.get = function (command) {
that.genericRequest(command, "get");
};
/**
* Get the document from all sub storages, get the fastest.
* @method get
* @param {object} command The JIO command
*/
that.get = function (command) {
that.genericRequest(command, "get");
};
/**
* Get the attachment from all sub storages, get the fastest.
* @method getAttachment
* @param {object} command The JIO command
*/
that.getAttachment = function (command) {
that.genericRequest(command, "getAttachment");
};
/**
* Get the attachment from all sub storages, get the fastest.
* @method getAttachment
* @param {object} command The JIO command
*/
that.getAttachment = function (command) {
that.genericRequest(command, "getAttachment");
};
/**
* Remove the document from all sub storages.
* @method remove
* @param {object} command The JIO command
*/
that.remove = function (command) {
that.genericRequest(command, "remove");
};
/**
* Remove the document from all sub storages.
* @method remove
* @param {object} command The JIO command
*/
that.remove = function (command) {
that.genericRequest(command, "remove");
};
/**
* Remove the attachment from all sub storages.
* @method remove
* @param {object} command The JIO command
*/
that.removeAttachment = function (command) {
that.genericRequest(command, "removeAttachment");
};
/**
* Remove the attachment from all sub storages.
* @method remove
* @param {object} command The JIO command
*/
that.removeAttachment = function (command) {
that.genericRequest(command, "removeAttachment");
};
return that;
});
return that;
});
}));
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