Commit e5ac3ede authored by Tristan Cavelier's avatar Tristan Cavelier

getAttachment and remaveAttachment added to the JIO API + test updated

jio.get({"_id": "a/b"});
changed to
jio.getAttachment({"_id": "a", "_attachment": "b"});
parent 04f8deb9
...@@ -375,6 +375,7 @@ var checkCommand = function (spec, my) { ...@@ -375,6 +375,7 @@ var checkCommand = function (spec, my) {
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */ /*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global postCommand: true, putCommand: true, getCommand: true, /*global postCommand: true, putCommand: true, getCommand: true,
removeCommand: true, allDocsCommand: true, removeCommand: true, allDocsCommand: true,
getAttachmentCommand: true, removeAttachmentCommand: true,
putAttachmentCommand: true, failStatus: true, doneStatus: true, putAttachmentCommand: true, failStatus: true, doneStatus: true,
checkCommand: true, repairCommand: true, checkCommand: true, repairCommand: true,
hex_md5: true */ hex_md5: true */
...@@ -391,7 +392,9 @@ var command = function (spec, my) { ...@@ -391,7 +392,9 @@ var command = function (spec, my) {
'get': getCommand, 'get': getCommand,
'remove': removeCommand, 'remove': removeCommand,
'allDocs': allDocsCommand, 'allDocs': allDocsCommand,
'getAttachment': getAttachmentCommand,
'putAttachment': putAttachmentCommand, 'putAttachment': putAttachmentCommand,
'removeAttachment': removeAttachmentCommand,
'check': checkCommand, 'check': checkCommand,
'repair': repairCommand 'repair': repairCommand
}; };
...@@ -409,7 +412,6 @@ var command = function (spec, my) { ...@@ -409,7 +412,6 @@ var command = function (spec, my) {
"_id": priv.doc.toString() "_id": priv.doc.toString()
}; };
} }
priv.docid = spec.docid || priv.doc._id;
priv.option = spec.options || {}; priv.option = spec.options || {};
priv.callbacks = spec.callbacks || {}; priv.callbacks = spec.callbacks || {};
priv.success = [priv.callbacks.success || function () {}]; priv.success = [priv.callbacks.success || function () {}];
...@@ -456,10 +458,7 @@ var command = function (spec, my) { ...@@ -456,10 +458,7 @@ var command = function (spec, my) {
* @return {string} The document id * @return {string} The document id
*/ */
that.getDocId = function () { that.getDocId = function () {
if (typeof priv.docid !== "string") { return priv.doc._id;
return undefined;
}
return priv.docid.split('/')[0];
}; };
/** /**
...@@ -468,19 +467,7 @@ var command = function (spec, my) { ...@@ -468,19 +467,7 @@ var command = function (spec, my) {
* @return {string} The attachment id * @return {string} The attachment id
*/ */
that.getAttachmentId = function () { that.getAttachmentId = function () {
if (typeof priv.docid !== "string") { return priv.doc._attachment;
return undefined;
}
return priv.docid.split('/')[1];
};
/**
* Returns the label of the command.
* @method getDoc
* @return {object} The document.
*/
that.getDoc = function () {
return priv.doc;
}; };
/** /**
...@@ -544,8 +531,8 @@ var command = function (spec, my) { ...@@ -544,8 +531,8 @@ var command = function (spec, my) {
* @param {object} storage The storage. * @param {object} storage The storage.
*/ */
that.validate = function (storage) { that.validate = function (storage) {
if (typeof priv.docid === "string" && if (typeof priv.doc._id === "string" &&
!priv.docid.match("^[^\/]+([\/][^\/]+)?$")) { !priv.doc._id.match("^[^\/]+([\/][^\/]+)?$")) {
that.error({ that.error({
status: 21, status: 21,
statusText: 'Invalid Document Id', statusText: 'Invalid Document Id',
...@@ -708,6 +695,58 @@ var command = function (spec, my) { ...@@ -708,6 +695,58 @@ var command = function (spec, my) {
}; };
/*jslint indent: 2, maxlen: 80, sloppy: true */ /*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */ /*global command: true */
var getAttachmentCommand = function (spec, my) {
var that = command(spec, my);
spec = spec || {};
my = my || {};
// Attributes //
// Methods //
that.getLabel = function () {
return 'getAttachment';
};
that.executeOn = function (storage) {
storage.getAttachment(that);
};
that.validateState = function () {
if (!(typeof that.getDocId() === "string" && that.getDocId() !==
"")) {
that.error({
"status": 20,
"statusText": "Document Id Required",
"error": "document_id_required",
"message": "The document id is not provided",
"reason": "Document id is undefined"
});
return false;
}
if (typeof that.getAttachmentId() !== "string") {
that.error({
"status": 22,
"statusText": "Attachment Id Required",
"error": "attachment_id_required",
"message": "The attachment id must be set",
"reason": "Attachment id not set"
});
return false;
}
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
}
return true;
};
return that;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var getCommand = function (spec, my) { var getCommand = function (spec, my) {
var that = command(spec, my); var that = command(spec, my);
...@@ -731,18 +770,6 @@ var getCommand = function (spec, my) { ...@@ -731,18 +770,6 @@ var getCommand = function (spec, my) {
}); });
return false; return false;
} }
if (typeof that.getAttachmentId() === "string") {
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
return false;
}
}
return true; return true;
}; };
...@@ -770,17 +797,6 @@ var postCommand = function (spec, my) { ...@@ -770,17 +797,6 @@ var postCommand = function (spec, my) {
}; };
that.validateState = function () { that.validateState = function () {
if (that.getAttachmentId() !== undefined) {
that.error({
"status": 21,
"statusText": "Invalid Document Id",
"error": "invalid_document_id",
"message": "The document id contains '/' characters " +
"which are forbidden",
"reason": "Document id contains '/' character(s)"
});
return false;
}
return true; return true;
}; };
that.executeOn = function (storage) { that.executeOn = function (storage) {
...@@ -864,22 +880,63 @@ var putCommand = function (spec, my) { ...@@ -864,22 +880,63 @@ var putCommand = function (spec, my) {
}); });
return false; return false;
} }
if (that.getAttachmentId() !== undefined) { return true;
};
that.executeOn = function (storage) {
storage.put(that);
};
return that;
};
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var removeAttachmentCommand = function (spec, my) {
var that = command(spec, my);
spec = spec || {};
my = my || {};
// Attributes //
// Methods //
that.getLabel = function () {
return 'removeAttachment';
};
that.executeOn = function (storage) {
storage.removeAttachment(that);
};
that.validateState = function () {
if (!(typeof that.getDocId() === "string" && that.getDocId() !==
"")) {
that.error({
"status": 20,
"statusText": "Document Id Required",
"error": "document_id_required",
"message": "The document id is not provided",
"reason": "Document id is undefined"
});
return false;
}
if (typeof that.getAttachmentId() !== "string") {
that.error({ that.error({
"status": 21, "status": 22,
"statusText": "Invalid Document Id", "statusText": "Attachment Id Required",
"error": "invalid_document_id", "error": "attachment_id_required",
"message": "The document id contains '/' characters " + "message": "The attachment id must be set",
"which are forbidden", "reason": "Attachment id not set"
"reason": "Document id contains '/' character(s)"
}); });
return false; return false;
} }
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
}
return true; return true;
}; };
that.executeOn = function (storage) {
storage.put(that);
};
return that; return that;
}; };
/*jslint indent: 2, maxlen: 80, sloppy: true */ /*jslint indent: 2, maxlen: 80, sloppy: true */
...@@ -906,18 +963,6 @@ var removeCommand = function (spec, my) { ...@@ -906,18 +963,6 @@ var removeCommand = function (spec, my) {
}); });
return false; return false;
} }
if (typeof that.getAttachmentId() === "string") {
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
return false;
}
}
return true; return true;
}; };
...@@ -2158,6 +2203,7 @@ var jobRules = (function () { ...@@ -2158,6 +2203,7 @@ var jobRules = (function () {
storage_type_object: true, invalidStorageType: true, jobRules: true, storage_type_object: true, invalidStorageType: true, jobRules: true,
job: true, postCommand: true, putCommand: true, getCommand:true, job: true, postCommand: true, putCommand: true, getCommand:true,
allDocsCommand: true, putAttachmentCommand: true, allDocsCommand: true, putAttachmentCommand: true,
getAttachmentCommand: true, removeAttachmentCommand: true,
removeCommand: true, checkCommand: true, repairCommand: true */ removeCommand: true, checkCommand: true, repairCommand: true */
// Class jio // Class jio
var that = {}, priv = {}, jio_id_array_name = 'jio/id_array'; var that = {}, priv = {}, jio_id_array_name = 'jio/id_array';
...@@ -2367,12 +2413,13 @@ priv.addJob = function (commandCreator, spec) { ...@@ -2367,12 +2413,13 @@ priv.addJob = function (commandCreator, spec) {
* Post a document. * Post a document.
* @method post * @method post
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id (optional), "/" are forbidden * - {string} _id The document id (optional)
* For revision managing: choose at most one of the following informations:
* - {string} _rev The revision we want to update
* - {string} _revs_info The revision information we want the document to have
* - {string} _revs The revision history we want the document to have
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Retreive the revisions.
* - {boolean} conflicts Retreive the conflict list.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -2400,12 +2447,13 @@ Object.defineProperty(that, "post", { ...@@ -2400,12 +2447,13 @@ Object.defineProperty(that, "post", {
* Put a document. * Put a document.
* @method put * @method put
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id, "/" are forbidden * - {string} _id The document id
* For revision managing: choose at most one of the following informations:
* - {string} _rev The revision we want to update
* - {string} _revs_info The revision information we want the document to have
* - {string} _revs The revision history we want the document to have
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Retreive the revisions.
* - {boolean} conflicts Retreive the conflict list.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -2433,10 +2481,12 @@ Object.defineProperty(that, "put", { ...@@ -2433,10 +2481,12 @@ Object.defineProperty(that, "put", {
* Get a document. * Get a document.
* @method get * @method get
* @param {string} doc The document object. Contains at least: * @param {string} doc The document object. Contains at least:
* - {string} _id The document id: "doc_id" or "doc_id/attachment_id" * - {string} _id The document id
* For revision managing:
* - {string} _rev The revision we want to get. (optional)
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {string} rev The revision we want to get. * For revision managing:
* - {boolean} revs Include revision history of the document. * - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include list of revisions, and their availability. * - {boolean} revs_info Include list of revisions, and their availability.
* - {boolean} conflicts Include a list of conflicts. * - {boolean} conflicts Include a list of conflicts.
...@@ -2467,12 +2517,11 @@ Object.defineProperty(that, "get", { ...@@ -2467,12 +2517,11 @@ Object.defineProperty(that, "get", {
* Remove a document. * Remove a document.
* @method remove * @method remove
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id: "doc_id" or "doc_id/attachment_id" * - {string} _id The document id
* For revision managing:
* - {string} _rev The revision we want to remove
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include list of revisions, and their availability.
* - {boolean} conflicts Include a list of conflicts.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -2502,9 +2551,6 @@ Object.defineProperty(that, "remove", { ...@@ -2502,9 +2551,6 @@ Object.defineProperty(that, "remove", {
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} include_docs Include document metadata * - {boolean} include_docs Include document metadata
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include revisions.
* - {boolean} conflicts Include conflicts.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -2527,19 +2573,51 @@ Object.defineProperty(that, "allDocs", { ...@@ -2527,19 +2573,51 @@ Object.defineProperty(that, "allDocs", {
} }
}); });
/**
* Get an attachment from a document.
* @method gettAttachment
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* - {string} _attachment The attachment id
* For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object.defineProperty(that, "getAttachment", {
configurable: false,
enumerable: false,
writable: false,
value: function (doc, options, success, error) {
var param = priv.parametersToObject(
[options, success, error],
{max_retry: 3}
);
priv.addJob(getAttachmentCommand, {
doc: doc,
options: param.options,
callbacks: {success: param.success, error: param.error}
});
}
});
/** /**
* Put an attachment to a document. * Put an attachment to a document.
* @method putAttachment * @method putAttachment
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id: "doc_id/attchment_id" * - {string} _id The document id
* - {string} _data Base64 attachment data * - {string} _attachment The attachment id
* - {string} _data The attachment data
* - {string} _mimetype The attachment mimetype * - {string} _mimetype The attachment mimetype
* - {string} _rev The attachment revision * For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include revisions.
* - {boolean} conflicts Include conflicts.
* @param {function} callback (optional) The callback(err,respons) * @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -2563,6 +2641,39 @@ Object.defineProperty(that, "putAttachment", { ...@@ -2563,6 +2641,39 @@ Object.defineProperty(that, "putAttachment", {
} }
}); });
/**
* Put an attachment to a document.
* @method putAttachment
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* - {string} _attachment The attachment id
* For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object.defineProperty(that, "removeAttachment", {
configurable: false,
enumerable: false,
writable: false,
value: function (doc, options, success, error) {
var param = priv.parametersToObject(
[options, success, error],
{max_retry: 0}
);
priv.addJob(removeAttachmentCommand, {
doc: doc,
options: param.options,
callbacks: {success: param.success, error: param.error}
});
}
});
/** /**
* Check a document. * Check a document.
* @method check * @method check
......
...@@ -45,16 +45,14 @@ ...@@ -45,16 +45,14 @@
setTimeout(function () { setTimeout(function () {
that.success({ that.success({
"ok": true, "ok": true,
"id": command.getDocId() + "/" + command.getAttachmentId() "id": command.getDocId(),
"attachment": command.getAttachmentId()
}); });
}, 100); // 100 ms, for jiotests simple job waiting }, 100); // 100 ms, for jiotests simple job waiting
}; // end putAttachment }; // end putAttachment
that.get = function (command) { that.get = function (command) {
setTimeout(function () { setTimeout(function () {
if (command.getAttachmentId()) {
return that.success('0123456789');
}
that.success({ that.success({
"_id": command.getDocId(), "_id": command.getDocId(),
"title": 'get_title' "title": 'get_title'
...@@ -62,34 +60,43 @@ ...@@ -62,34 +60,43 @@
}, 100); // 100 ms, for jiotests simple job waiting }, 100); // 100 ms, for jiotests simple job waiting
}; // end get }; // end get
that.getAttachment = function (command) {
setTimeout(function () {
that.success('0123456789');
}, 100); // 100 ms, for jiotests simple job waiting
}; // end putAttachment
that.allDocs = function () { that.allDocs = function () {
setTimeout(function () { setTimeout(function () {
that.error({ that.error({
"status": 405, "status": 405,
"statusText": "Method Not Allowed", "statusText": "Method Not Allowed",
"error": "method_not_allowed", "error": "method_not_allowed",
"message": "Your are not allowed to use" + "this command", "message": "Your are not allowed to use this command",
"reason": "LocalStorage forbids AllDocs" + "command executions" "reason": "Dummystorage forbids AllDocs command executions"
}); });
}); });
}; // end allDocs }; // end allDocs
that.remove = function (command) { that.remove = function (command) {
setTimeout(function () { setTimeout(function () {
if (command.getAttachmentId()) { that.success({
that.success({ "ok": true,
"ok": true, "id": command.getDocId()
"id": command.getDocId() + "/" + command.getAttachmentId() });
});
} else {
that.success({
"ok": true,
"id": command.getDocId()
});
}
}, 100); // 100 ms, for jiotests simple job waiting }, 100); // 100 ms, for jiotests simple job waiting
}; // end remove }; // end remove
that.removeAttachment = function (command) {
setTimeout(function () {
that.success({
"ok": true,
"id": command.getDocId(),
"attachment": command.getAttachmentId()
});
}, 100); // 100 ms, for jiotests simple job waiting
}; // end putAttachment
return that; return that;
}, },
// end Dummy Storage All Ok // end Dummy Storage All Ok
...@@ -130,6 +137,10 @@ ...@@ -130,6 +137,10 @@
priv.error(); priv.error();
}; // end get }; // end get
that.getAttachment = function () {
priv.error();
};
that.allDocs = function () { that.allDocs = function () {
setTimeout(function () { setTimeout(function () {
that.error({ that.error({
...@@ -145,6 +156,11 @@ ...@@ -145,6 +156,11 @@
that.remove = function () { that.remove = function () {
priv.error(); priv.error();
}; // end remove }; // end remove
that.removeAttachment = function () {
priv.error();
};
return that; return that;
}, },
// end Dummy Storage All Fail // end Dummy Storage All Fail
...@@ -177,7 +193,8 @@ ...@@ -177,7 +193,8 @@
setTimeout(function () { setTimeout(function () {
that.success({ that.success({
"ok": true, "ok": true,
"id": command.getDocId() + "/" + command.getAttachmentId() "id": command.getDocId(),
"attachment": command.getAttachmentId()
}); });
}, 100); }, 100);
}; // end put }; // end put
...@@ -193,28 +210,55 @@ ...@@ -193,28 +210,55 @@
}); });
}, 100); }, 100);
}; // end get }; // end get
that.getAttachment = function (command) {
setTimeout(function () {
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Attachment not found",
"reason": "Document '" + command.getDocId() + "'does not exist"
});
}, 100);
}; // end get
that.allDocs = function () { that.allDocs = function () {
setTimeout(function () { setTimeout(function () {
that.error({ that.error({
"status": 405, "status": 405,
"statusText": "Method Not Allowed", "statusText": "Method Not Allowed",
"error": "method_not_allowed", "error": "method_not_allowed",
"message": "Your are not allowed to use" + "this command", "message": "Your are not allowed to use this command",
"reason": "LocalStorage forbids AllDocs" + "command executions" "reason": "Dummystorage forbids AllDocs command executions"
}); });
}); });
}; // end allDocs }; // end allDocs
that.remove = function () { that.remove = function () {
setTimeout(function () { setTimeout(function () {
that.error({ that.error({
"status": 404, "status": 404,
"statusText": "Not Found", "statusText": "Not Found",
"error": "not_found", "error": "not_found",
"message": "Cannot remove an unexistant" + "document", "message": "Cannot remove an inexistent document",
"reason": "missing" // or deleted "reason": "missing" // or deleted
}); });
}, 100); }, 100);
}; // end remove }; // end remove
that.removeAttachment = function () {
setTimeout(function () {
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Cannot remove an inexistent attachment",
"reason": "missing" // or deleted
});
}, 100);
}; // end remove
return that; return that;
}, },
// end Dummy Storage All Not Found // end Dummy Storage All Not Found
...@@ -449,45 +493,50 @@ ...@@ -449,45 +493,50 @@
setTimeout(function () { setTimeout(function () {
that.success({ that.success({
"ok": true, "ok": true,
"id": command.getDocId() + "/" + command.getAttachmentId() "id": command.getDocId(),
"attachment": command.getAttachmentId()
}); });
}, 100); }, 100);
}; // end put }; // end putAttachment
that.get = function (command) { that.get = function (command) {
setTimeout(function () { setTimeout(function () {
if (command.getAttachmentId()) {
return that.success('0123456789');
}
that.success({ that.success({
"_id": command.getDocId(), "_id": command.getDocId(),
"title": 'get_title' "title": 'get_title'
}); });
}, 100); // 100 ms, for jiotests simple job waiting }, 100); // 100 ms, for jiotests simple job waiting
}; // end get }; // end get
that.getAttachment = function (command) {
setTimeout(function () {
that.success('0123456789');
}, 100); // 100 ms, for jiotests simple job waiting
}; // end getAttachment
that.allDocs = function () { that.allDocs = function () {
setTimeout(function () { setTimeout(function () {
that.error({ that.error({
"status": 405, "status": 405,
"statusText": "Method Not Allowed", "statusText": "Method Not Allowed",
"error": "method_not_allowed", "error": "method_not_allowed",
"message": "Your are not allowed to use" + "this command", "message": "Your are not allowed to use this command",
"reason": "LocalStorage forbids AllDocs" + "command executions" "reason": "Dummystorage forbids AllDocs command executions"
}); });
}); });
}; // end allDocs }; // end allDocs
that.remove = function (command) { that.remove = function (command) {
setTimeout(function () { setTimeout(function () {
if (command.getAttachmentId()) { that.success({
that.success({ "ok": true,
"ok": true, "id": command.getDocId()
"id": command.getDocId() + "/" + command.getAttachmentId() });
}); }, 100); // 100 ms, for jiotests simple job waiting
} else { }; // end remove
that.success({ that.removeAttachment = function (command) {
"ok": true, setTimeout(function () {
"id": command.getDocId() that.success({
}); "ok": true,
} "id": command.getDocId(),
"attachment": command.getAttachmentId()
});
}, 100); // 100 ms, for jiotests simple job waiting }, 100); // 100 ms, for jiotests simple job waiting
}; // end remove }; // end remove
return that; return that;
......
...@@ -569,22 +569,17 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -569,22 +569,17 @@ jIO.addStorageType('indexed', function (spec, my) {
* @param {string} source The source of the function call * @param {string} source The source of the function call
*/ */
priv.postOrPut = function (command, source) { priv.postOrPut = function (command, source) {
var f = {}, indices, doc, docid; var f = {}, indices, doc;
doc = command.cloneDoc(); doc = command.cloneDoc();
docid = command.getDocId(); if (typeof doc._id !== "string") {
if (typeof docid !== "string") {
doc._id = priv.generateUuid(); doc._id = priv.generateUuid();
docid = doc._id;
} }
f.getIndices = function () { f.getIndices = function () {
var option = command.cloneOption(); var option = command.cloneOption();
if (option.max_retry === 0) {
option.max_retry = 3;
}
that.addJob( that.addJob(
"get", "get",
priv.substorage, priv.substorage,
priv.index_suffix, {"_id": priv.index_suffix},
option, option,
function (response) { function (response) {
indices = response; indices = response;
...@@ -639,10 +634,10 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -639,10 +634,10 @@ jIO.addStorageType('indexed', function (spec, my) {
if (source !== 'PUTATTACHMENT') { if (source !== 'PUTATTACHMENT') {
f.sendIndices(index_update_method); f.sendIndices(index_update_method);
} else { } else {
docid = docid + '/' + command.getAttachmentId();
that.success({ that.success({
"ok": true, "ok": true,
"id": docid "id": doc._id,
"attachment": doc._attachment
}); });
} }
}, },
...@@ -655,7 +650,7 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -655,7 +650,7 @@ jIO.addStorageType('indexed', function (spec, my) {
} else { } else {
that.success({ that.success({
"ok": true, "ok": true,
"id": docid "id": doc._id
}); });
} }
break; break;
...@@ -677,7 +672,7 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -677,7 +672,7 @@ jIO.addStorageType('indexed', function (spec, my) {
function () { function () {
that.success({ that.success({
"ok": true, "ok": true,
"id": docid "id": doc._id
}); });
}, },
function (err) { function (err) {
...@@ -718,47 +713,47 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -718,47 +713,47 @@ jIO.addStorageType('indexed', function (spec, my) {
}; };
/** /**
* Get the document metadata or attachment. * Get the document metadata
* Options:
* - {boolean} revs Add simple revision history (false by default).
* - {boolean} revs_info Add revs info (false by default).
* - {boolean} conflicts Add conflict object (false by default).
* @method get * @method get
* @param {object} command The JIO command * @param {object} command The JIO command
*/ */
that.get = function (command) { that.get = function (command) {
var option, docid;
option = command.cloneOption();
if (option.max_retry === 0) {
option.max_retry = 3;
}
if (command.getAttachmentId() !== undefined) {
docid = command.getDocId() + '/' + command.getAttachmentId();
} else {
docid = command.getDocId();
}
that.addJob( that.addJob(
"get", "get",
priv.substorage, priv.substorage,
docid, command.cloneDoc(),
option, command.cloneOption(),
function (response) { function (response) {
that.success(response); that.success(response);
}, },
function () { function (err) {
that.error({ that.error(err);
"status": 404, }
"statusText": "Not Found", );
"error": "not_found", };
"message": "Cannot find the attachment",
"reason": "Document/Attachment not found" /**
}); * Get the attachment.
* @method getAttachment
* @param {object} command The JIO command
*/
that.getAttachment = function (command) {
that.addJob(
"getAttachment",
priv.substorage,
command.cloneDoc(),
command.cloneOption(),
function (response) {
that.success(response);
},
function (err) {
that.error(err);
} }
); );
}; };
/** /**
* Remove document or attachment - removing documents updates index!. * Remove document - removing documents updates index!.
* @method remove * @method remove
* @param {object} command The JIO command * @param {object} command The JIO command
*/ */
...@@ -767,20 +762,12 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -767,20 +762,12 @@ jIO.addStorageType('indexed', function (spec, my) {
doc = command.cloneDoc(); doc = command.cloneDoc();
option = command.cloneOption(); option = command.cloneOption();
if (option.max_retry === 0) {
option.max_retry = 3;
}
f.removeDocument = function (type) { f.removeDocument = function (type) {
if (type === 'doc') {
docid = command.getDocId();
} else {
docid = command.getDocId() + '/' + command.getAttachmentId();
}
that.addJob( that.addJob(
"remove", "remove",
priv.substorage, priv.substorage,
docid, doc,
option, option,
function (response) { function (response) {
that.success(response); that.success(response);
...@@ -800,7 +787,7 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -800,7 +787,7 @@ jIO.addStorageType('indexed', function (spec, my) {
that.addJob( that.addJob(
"get", "get",
priv.substorage, priv.substorage,
priv.index_suffix, {"_id": priv.index_suffix},
option, option,
function (response) { function (response) {
// if deleting an attachment // if deleting an attachment
...@@ -840,6 +827,62 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -840,6 +827,62 @@ jIO.addStorageType('indexed', function (spec, my) {
f.getIndices(); f.getIndices();
}; };
/**
* Remove document - removing documents updates index!.
* @method remove
* @param {object} command The JIO command
*/
that.removeAttachment = function (command) {
var f = {}, indices, doc, docid, option;
doc = command.cloneDoc();
option = command.cloneOption();
f.removeDocument = function (type) {
that.addJob(
"removeAttachment",
priv.substorage,
doc,
option,
that.success,
that.error
);
};
f.getIndices = function () {
that.addJob(
"get",
priv.substorage,
{"_id": priv.index_suffix},
option,
function (response) {
// if deleting an attachment
if (typeof command.getAttachmentId() === 'string') {
f.removeDocument('attachment');
} else {
indices = priv.cleanIndices(response, doc);
// store update index file
that.addJob(
"put",
priv.substorage,
indices,
command.cloneOption(),
function () {
// remove actual document
f.removeDocument('doc');
},
function (err) {
err.message = "Cannot save index file";
that.error(err);
}
);
}
},
function (err) {
that.error(err);
}
);
};
f.getIndices();
};
/** /**
* Gets a document list from the substorage * Gets a document list from the substorage
* Options: * Options:
...@@ -863,15 +906,12 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -863,15 +906,12 @@ jIO.addStorageType('indexed', function (spec, my) {
var f = {}, option, all_docs_response, query_object, query_syntax, var f = {}, option, all_docs_response, query_object, query_syntax,
query_response; query_response;
option = command.cloneOption(); option = command.cloneOption();
if (option.max_retry === 0) {
option.max_retry = 3;
}
f.getIndices = function () { f.getIndices = function () {
that.addJob( that.addJob(
"get", "get",
priv.substorage, priv.substorage,
priv.index_suffix, {"_id": priv.index_suffix},
option, option,
function (response) { function (response) {
query_syntax = command.getOption('query'); query_syntax = command.getOption('query');
...@@ -887,31 +927,8 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -887,31 +927,8 @@ jIO.addStorageType('indexed', function (spec, my) {
priv.substorage, priv.substorage,
undefined, undefined,
option, option,
function (data) { that.success,
that.success(data); that.error
},
function (err) {
switch (err.status) {
case 405:
that.error({
"status": 405,
"statusText": "Method Not Allowed",
"error": "method_not_allowed",
"message": "Method not allowed",
"reason": "Could not run AllDocs on this storage"
});
break;
default:
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Could not run allDocs command",
"reason": "There are no documents in the storage"
});
break;
}
}
); );
} else { } else {
// we can use index, run query on index // we can use index, run query on index
...@@ -927,16 +944,7 @@ jIO.addStorageType('indexed', function (spec, my) { ...@@ -927,16 +944,7 @@ jIO.addStorageType('indexed', function (spec, my) {
that.success(all_docs_response); that.success(all_docs_response);
} }
}, },
function () { that.error
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Document index not found",
"reason": "There are no documents in the storage"
});
return;
}
); );
}; };
f.getIndices(); f.getIndices();
......
...@@ -203,58 +203,104 @@ jIO.addStorageType('local', function (spec, my) { ...@@ -203,58 +203,104 @@ jIO.addStorageType('local', function (spec, my) {
localstorage.setItem(priv.localpath + "/" + command.getDocId(), doc); localstorage.setItem(priv.localpath + "/" + command.getDocId(), doc);
that.success({ that.success({
"ok": true, "ok": true,
"id": command.getDocId() + "/" + command.getAttachmentId() "id": command.getDocId(),
"attachment": command.getAttachmentId()
}); });
}); });
}; };
/** /**
* Get a document or attachment * Get a document
* @method get * @method get
* @param {object} command The JIO command * @param {object} command The JIO command
*/ */
that.get = function (command) { that.get = function (command) {
setTimeout(function () { setTimeout(function () {
var doc; var doc = localstorage.getItem(priv.localpath + "/" + command.getDocId());
if (typeof command.getAttachmentId() === "string") { if (doc !== null) {
// seeking for an attachment that.success(doc);
doc = localstorage.getItem(priv.localpath + "/" + command.getDocId() +
"/" + command.getAttachmentId());
if (doc !== null) {
that.success(doc);
} else {
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Cannot find the attachment",
"reason": "Attachment does not exist"
});
}
} else { } else {
// seeking for a document that.error({
doc = localstorage.getItem(priv.localpath + "/" + command.getDocId()); "status": 404,
if (doc !== null) { "statusText": "Not Found",
that.success(doc); "error": "not_found",
} else { "message": "Cannot find the document",
that.error({ "reason": "Document does not exist"
"status": 404, });
"statusText": "Not Found",
"error": "not_found",
"message": "Cannot find the document",
"reason": "Document does not exist"
});
}
} }
}); });
}; };
/** /**
* Remove a document or attachment * Get a attachment
* @method getAttachment
* @param {object} command The JIO command
*/
that.getAttachment = function (command) {
setTimeout(function () {
var doc = localstorage.getItem(priv.localpath + "/" + command.getDocId() +
"/" + command.getAttachmentId());
if (doc !== null) {
that.success(doc);
} else {
that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Cannot find the attachment",
"reason": "Attachment does not exist"
});
}
});
};
/**
* Remove a document
* @method remove * @method remove
* @param {object} command The JIO command * @param {object} command The JIO command
*/ */
that.remove = function (command) { that.remove = function (command) {
setTimeout(function () {
var doc, i, attachment_list;
doc = localstorage.getItem(priv.localpath + "/" + command.getDocId());
attachment_list = [];
if (doc !== null && typeof doc === "object") {
if (typeof doc._attachments === "object") {
// prepare list of attachments
for (i in doc._attachments) {
if (doc._attachments.hasOwnProperty(i)) {
attachment_list.push(i);
}
}
}
} else {
return that.error({
"status": 404,
"statusText": "Not Found",
"error": "not_found",
"message": "Document not found",
"reason": "missing"
});
}
localstorage.removeItem(priv.localpath + "/" + command.getDocId());
// delete all attachments
for (i = 0; i < attachment_list.length; i += 1) {
localstorage.removeItem(priv.localpath + "/" + command.getDocId() +
"/" + attachment_list[i]);
}
that.success({
"ok": true,
"id": command.getDocId()
});
});
};
/**
* Remove an attachment
* @method removeAttachment
* @param {object} command The JIO command
*/
that.removeAttachment = function (command) {
setTimeout(function () { setTimeout(function () {
var doc, error, i, attachment_list; var doc, error, i, attachment_list;
error = function (word) { error = function (word) {
...@@ -267,55 +313,29 @@ jIO.addStorageType('local', function (spec, my) { ...@@ -267,55 +313,29 @@ jIO.addStorageType('local', function (spec, my) {
}); });
}; };
doc = localstorage.getItem(priv.localpath + "/" + command.getDocId()); doc = localstorage.getItem(priv.localpath + "/" + command.getDocId());
if (typeof command.getAttachmentId() === "string") { // remove attachment from document
// remove attachment from document if (doc !== null && typeof doc === "object" &&
if (doc !== null && typeof doc === "object" && typeof doc._attachments === "object") {
typeof doc._attachments === "object") { if (typeof doc._attachments[command.getAttachmentId()] ===
if (typeof doc._attachments[command.getAttachmentId()] === "object") {
"object") { delete doc._attachments[command.getAttachmentId()];
delete doc._attachments[command.getAttachmentId()]; if (priv.objectIsEmpty(doc._attachments)) {
if (priv.objectIsEmpty(doc._attachments)) { delete doc._attachments;
delete doc._attachments;
}
localstorage.setItem(priv.localpath + "/" + command.getDocId(),
doc);
localstorage.removeItem(priv.localpath + "/" + command.getDocId() +
"/" + command.getAttachmentId());
that.success({
"ok": true,
"id": command.getDocId() + "/" + command.getAttachmentId()
});
} else {
error("Attachment");
} }
localstorage.setItem(priv.localpath + "/" + command.getDocId(),
doc);
localstorage.removeItem(priv.localpath + "/" + command.getDocId() +
"/" + command.getAttachmentId());
that.success({
"ok": true,
"id": command.getDocId(),
"attachment": command.getAttachmentId()
});
} else { } else {
error("Document"); error("Attachment");
} }
} else { } else {
// seeking for a document error("Document");
attachment_list = [];
if (doc !== null && typeof doc === "object") {
if (typeof doc._attachments === "object") {
// prepare list of attachments
for (i in doc._attachments) {
if (doc._attachments.hasOwnProperty(i)) {
attachment_list.push(i);
}
}
}
} else {
return error("Document");
}
localstorage.removeItem(priv.localpath + "/" + command.getDocId());
// delete all attachments
for (i = 0; i < attachment_list.length; i += 1) {
localstorage.removeItem(priv.localpath + "/" + command.getDocId() +
"/" + attachment_list[i]);
}
that.success({
"ok": true,
"id": command.getDocId()
});
} }
}); });
}; };
......
...@@ -413,10 +413,11 @@ jIO.addStorageType('replicaterevision', function (spec, my) { ...@@ -413,10 +413,11 @@ jIO.addStorageType('replicaterevision', function (spec, my) {
if ((parsed_response._attachments).hasOwnProperty(attachment)) { if ((parsed_response._attachments).hasOwnProperty(attachment)) {
functions.get_attachment_count += 1; functions.get_attachment_count += 1;
priv.send( priv.send(
"get", "getAttachment",
param.responses.stats[response][0], param.responses.stats[response][0],
{ {
"_id": param.doc._id + "/" + attachment, "_id": param.doc._id,
"_attachment": attachment,
"_rev": JSON.parse(response)._rev "_rev": JSON.parse(response)._rev
}, },
param.option, param.option,
...@@ -550,8 +551,6 @@ jIO.addStorageType('replicaterevision', function (spec, my) { ...@@ -550,8 +551,6 @@ jIO.addStorageType('replicaterevision', function (spec, my) {
// "_revs_info": param.responses.list[index]._revs_info, // "_revs_info": param.responses.list[index]._revs_info,
"_data": param.responses.attachments[attachment_to_put[i]._id] "_data": param.responses.attachments[attachment_to_put[i]._id]
}; };
attachment._id += "/" + attachment._attachment;
delete attachment._attachment;
priv.send( priv.send(
"putAttachment", "putAttachment",
index, index,
......
...@@ -366,9 +366,15 @@ jIO.addStorageType("revision", function (spec, my) { ...@@ -366,9 +366,15 @@ jIO.addStorageType("revision", function (spec, my) {
priv.remove = function (doc, option, callback) { priv.remove = function (doc, option, callback) {
priv.send("remove", doc, option, callback); priv.send("remove", doc, option, callback);
}; };
priv.getAttachment = function (attachment, option, callback) {
priv.send("getAttachment", attachment, option, callback);
};
priv.putAttachment = function (attachment, option, callback) { priv.putAttachment = function (attachment, option, callback) {
priv.send("putAttachment", attachment, option, callback); priv.send("putAttachment", attachment, option, callback);
}; };
priv.removeAttachment = function (attachment, option, callback) {
priv.send("removeAttachment", attachment, option, callback);
};
priv.getDocument = function (doc, option, callback) { priv.getDocument = function (doc, option, callback) {
doc = priv.clone(doc); doc = priv.clone(doc);
...@@ -379,7 +385,6 @@ jIO.addStorageType("revision", function (spec, my) { ...@@ -379,7 +385,6 @@ jIO.addStorageType("revision", function (spec, my) {
delete doc._revs_info; delete doc._revs_info;
priv.get(doc, option, callback); priv.get(doc, option, callback);
}; };
priv.getAttachment = priv.get;
priv.putDocument = function (doc, option, callback) { priv.putDocument = function (doc, option, callback) {
doc = priv.clone(doc); doc = priv.clone(doc);
doc._id = doc._id + "." + doc._rev; doc._id = doc._id + "." + doc._rev;
...@@ -428,8 +433,8 @@ jIO.addStorageType("revision", function (spec, my) { ...@@ -428,8 +433,8 @@ jIO.addStorageType("revision", function (spec, my) {
for (attachment_id in doc._attachments) { for (attachment_id in doc._attachments) {
if (doc._attachments.hasOwnProperty(attachment_id)) { if (doc._attachments.hasOwnProperty(attachment_id)) {
count += 1; count += 1;
priv.get( priv.getAttachment(
{"_id": doc._id + "/" + attachment_id}, {"_id": doc._id, "_attachment": attachment_id},
option, option,
dealResults(attachment_id, doc._attachments[attachment_id]) dealResults(attachment_id, doc._attachments[attachment_id])
); );
...@@ -463,9 +468,7 @@ jIO.addStorageType("revision", function (spec, my) { ...@@ -463,9 +468,7 @@ jIO.addStorageType("revision", function (spec, my) {
attachment = attachment_list[i]; attachment = attachment_list[i];
if (attachment !== undefined) { if (attachment !== undefined) {
count += 1; count += 1;
attachment._id = doc._id + "." + doc._rev + "/" + attachment._id = doc._id + "." + doc._rev;
attachment._attachment;
delete attachment._attachment;
priv.putAttachment(attachment, option, dealResults(i)); priv.putAttachment(attachment, option, dealResults(i));
} }
} }
...@@ -729,18 +732,22 @@ jIO.addStorageType("revision", function (spec, my) { ...@@ -729,18 +732,22 @@ jIO.addStorageType("revision", function (spec, my) {
priv.putDocumentTree(doc, option, doc_tree, callback.putDocumentTree); priv.putDocumentTree(doc, option, doc_tree, callback.putDocumentTree);
}; };
callback.putDocumentTree = function (err, response) { callback.putDocumentTree = function (err, response) {
var response_object;
if (err) { if (err) {
err.message = "Cannot update the document history"; err.message = "Cannot update the document history";
return onEnd(err, undefined); return onEnd(err, undefined);
} }
onEnd(undefined, { response_object = {
"ok": true, "ok": true,
"id": doc._id + (specific_parameter.putAttachment || "id": doc._id,
specific_parameter.removeAttachment ||
specific_parameter.getAttachment ?
"/" + doc._attachment : ""),
"rev": doc._rev "rev": doc._rev
}); };
if (specific_parameter.putAttachment ||
specific_parameter.removeAttachment ||
specific_parameter.getAttachment) {
response_object.attachment = doc._attachment;
}
onEnd(undefined, response_object);
// if (option.keep_revision_history !== true) { // if (option.keep_revision_history !== true) {
// // priv.remove(prev_doc, option, function () { // // priv.remove(prev_doc, option, function () {
// // - change "available" status to "deleted" // // - change "available" status to "deleted"
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */ /*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global postCommand: true, putCommand: true, getCommand: true, /*global postCommand: true, putCommand: true, getCommand: true,
removeCommand: true, allDocsCommand: true, removeCommand: true, allDocsCommand: true,
getAttachmentCommand: true, removeAttachmentCommand: true,
putAttachmentCommand: true, failStatus: true, doneStatus: true, putAttachmentCommand: true, failStatus: true, doneStatus: true,
checkCommand: true, repairCommand: true, checkCommand: true, repairCommand: true,
hex_md5: true */ hex_md5: true */
...@@ -17,7 +18,9 @@ var command = function (spec, my) { ...@@ -17,7 +18,9 @@ var command = function (spec, my) {
'get': getCommand, 'get': getCommand,
'remove': removeCommand, 'remove': removeCommand,
'allDocs': allDocsCommand, 'allDocs': allDocsCommand,
'getAttachment': getAttachmentCommand,
'putAttachment': putAttachmentCommand, 'putAttachment': putAttachmentCommand,
'removeAttachment': removeAttachmentCommand,
'check': checkCommand, 'check': checkCommand,
'repair': repairCommand 'repair': repairCommand
}; };
...@@ -35,7 +38,6 @@ var command = function (spec, my) { ...@@ -35,7 +38,6 @@ var command = function (spec, my) {
"_id": priv.doc.toString() "_id": priv.doc.toString()
}; };
} }
priv.docid = spec.docid || priv.doc._id;
priv.option = spec.options || {}; priv.option = spec.options || {};
priv.callbacks = spec.callbacks || {}; priv.callbacks = spec.callbacks || {};
priv.success = [priv.callbacks.success || function () {}]; priv.success = [priv.callbacks.success || function () {}];
...@@ -82,10 +84,7 @@ var command = function (spec, my) { ...@@ -82,10 +84,7 @@ var command = function (spec, my) {
* @return {string} The document id * @return {string} The document id
*/ */
that.getDocId = function () { that.getDocId = function () {
if (typeof priv.docid !== "string") { return priv.doc._id;
return undefined;
}
return priv.docid.split('/')[0];
}; };
/** /**
...@@ -94,19 +93,7 @@ var command = function (spec, my) { ...@@ -94,19 +93,7 @@ var command = function (spec, my) {
* @return {string} The attachment id * @return {string} The attachment id
*/ */
that.getAttachmentId = function () { that.getAttachmentId = function () {
if (typeof priv.docid !== "string") { return priv.doc._attachment;
return undefined;
}
return priv.docid.split('/')[1];
};
/**
* Returns the label of the command.
* @method getDoc
* @return {object} The document.
*/
that.getDoc = function () {
return priv.doc;
}; };
/** /**
...@@ -170,8 +157,8 @@ var command = function (spec, my) { ...@@ -170,8 +157,8 @@ var command = function (spec, my) {
* @param {object} storage The storage. * @param {object} storage The storage.
*/ */
that.validate = function (storage) { that.validate = function (storage) {
if (typeof priv.docid === "string" && if (typeof priv.doc._id === "string" &&
!priv.docid.match("^[^\/]+([\/][^\/]+)?$")) { !priv.doc._id.match("^[^\/]+([\/][^\/]+)?$")) {
that.error({ that.error({
status: 21, status: 21,
statusText: 'Invalid Document Id', statusText: 'Invalid Document Id',
......
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var getAttachmentCommand = function (spec, my) {
var that = command(spec, my);
spec = spec || {};
my = my || {};
// Attributes //
// Methods //
that.getLabel = function () {
return 'getAttachment';
};
that.executeOn = function (storage) {
storage.getAttachment(that);
};
that.validateState = function () {
if (!(typeof that.getDocId() === "string" && that.getDocId() !==
"")) {
that.error({
"status": 20,
"statusText": "Document Id Required",
"error": "document_id_required",
"message": "The document id is not provided",
"reason": "Document id is undefined"
});
return false;
}
if (typeof that.getAttachmentId() !== "string") {
that.error({
"status": 22,
"statusText": "Attachment Id Required",
"error": "attachment_id_required",
"message": "The attachment id must be set",
"reason": "Attachment id not set"
});
return false;
}
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
}
return true;
};
return that;
};
...@@ -23,18 +23,6 @@ var getCommand = function (spec, my) { ...@@ -23,18 +23,6 @@ var getCommand = function (spec, my) {
}); });
return false; return false;
} }
if (typeof that.getAttachmentId() === "string") {
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
return false;
}
}
return true; return true;
}; };
......
...@@ -12,17 +12,6 @@ var postCommand = function (spec, my) { ...@@ -12,17 +12,6 @@ var postCommand = function (spec, my) {
}; };
that.validateState = function () { that.validateState = function () {
if (that.getAttachmentId() !== undefined) {
that.error({
"status": 21,
"statusText": "Invalid Document Id",
"error": "invalid_document_id",
"message": "The document id contains '/' characters " +
"which are forbidden",
"reason": "Document id contains '/' character(s)"
});
return false;
}
return true; return true;
}; };
that.executeOn = function (storage) { that.executeOn = function (storage) {
......
...@@ -22,17 +22,6 @@ var putCommand = function (spec, my) { ...@@ -22,17 +22,6 @@ var putCommand = function (spec, my) {
}); });
return false; return false;
} }
if (that.getAttachmentId() !== undefined) {
that.error({
"status": 21,
"statusText": "Invalid Document Id",
"error": "invalid_document_id",
"message": "The document id contains '/' characters " +
"which are forbidden",
"reason": "Document id contains '/' character(s)"
});
return false;
}
return true; return true;
}; };
that.executeOn = function (storage) { that.executeOn = function (storage) {
......
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global command: true */
var removeAttachmentCommand = function (spec, my) {
var that = command(spec, my);
spec = spec || {};
my = my || {};
// Attributes //
// Methods //
that.getLabel = function () {
return 'removeAttachment';
};
that.executeOn = function (storage) {
storage.removeAttachment(that);
};
that.validateState = function () {
if (!(typeof that.getDocId() === "string" && that.getDocId() !==
"")) {
that.error({
"status": 20,
"statusText": "Document Id Required",
"error": "document_id_required",
"message": "The document id is not provided",
"reason": "Document id is undefined"
});
return false;
}
if (typeof that.getAttachmentId() !== "string") {
that.error({
"status": 22,
"statusText": "Attachment Id Required",
"error": "attachment_id_required",
"message": "The attachment id must be set",
"reason": "Attachment id not set"
});
return false;
}
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
}
return true;
};
return that;
};
...@@ -22,18 +22,6 @@ var removeCommand = function (spec, my) { ...@@ -22,18 +22,6 @@ var removeCommand = function (spec, my) {
}); });
return false; return false;
} }
if (typeof that.getAttachmentId() === "string") {
if (that.getAttachmentId() === "") {
that.error({
"status": 23,
"statusText": "Invalid Attachment Id",
"error": "invalid_attachment_id",
"message": "The attachment id must not be an empty string",
"reason": "Attachment id is empty"
});
return false;
}
}
return true; return true;
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
storage_type_object: true, invalidStorageType: true, jobRules: true, storage_type_object: true, invalidStorageType: true, jobRules: true,
job: true, postCommand: true, putCommand: true, getCommand:true, job: true, postCommand: true, putCommand: true, getCommand:true,
allDocsCommand: true, putAttachmentCommand: true, allDocsCommand: true, putAttachmentCommand: true,
getAttachmentCommand: true, removeAttachmentCommand: true,
removeCommand: true, checkCommand: true, repairCommand: true */ removeCommand: true, checkCommand: true, repairCommand: true */
// Class jio // Class jio
var that = {}, priv = {}, jio_id_array_name = 'jio/id_array'; var that = {}, priv = {}, jio_id_array_name = 'jio/id_array';
...@@ -213,12 +214,13 @@ priv.addJob = function (commandCreator, spec) { ...@@ -213,12 +214,13 @@ priv.addJob = function (commandCreator, spec) {
* Post a document. * Post a document.
* @method post * @method post
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id (optional), "/" are forbidden * - {string} _id The document id (optional)
* For revision managing: choose at most one of the following informations:
* - {string} _rev The revision we want to update
* - {string} _revs_info The revision information we want the document to have
* - {string} _revs The revision history we want the document to have
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Retreive the revisions.
* - {boolean} conflicts Retreive the conflict list.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -246,12 +248,13 @@ Object.defineProperty(that, "post", { ...@@ -246,12 +248,13 @@ Object.defineProperty(that, "post", {
* Put a document. * Put a document.
* @method put * @method put
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id, "/" are forbidden * - {string} _id The document id
* For revision managing: choose at most one of the following informations:
* - {string} _rev The revision we want to update
* - {string} _revs_info The revision information we want the document to have
* - {string} _revs The revision history we want the document to have
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Retreive the revisions.
* - {boolean} conflicts Retreive the conflict list.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -279,10 +282,12 @@ Object.defineProperty(that, "put", { ...@@ -279,10 +282,12 @@ Object.defineProperty(that, "put", {
* Get a document. * Get a document.
* @method get * @method get
* @param {string} doc The document object. Contains at least: * @param {string} doc The document object. Contains at least:
* - {string} _id The document id: "doc_id" or "doc_id/attachment_id" * - {string} _id The document id
* For revision managing:
* - {string} _rev The revision we want to get. (optional)
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {string} rev The revision we want to get. * For revision managing:
* - {boolean} revs Include revision history of the document. * - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include list of revisions, and their availability. * - {boolean} revs_info Include list of revisions, and their availability.
* - {boolean} conflicts Include a list of conflicts. * - {boolean} conflicts Include a list of conflicts.
...@@ -313,12 +318,11 @@ Object.defineProperty(that, "get", { ...@@ -313,12 +318,11 @@ Object.defineProperty(that, "get", {
* Remove a document. * Remove a document.
* @method remove * @method remove
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id: "doc_id" or "doc_id/attachment_id" * - {string} _id The document id
* For revision managing:
* - {string} _rev The revision we want to remove
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include list of revisions, and their availability.
* - {boolean} conflicts Include a list of conflicts.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -348,9 +352,6 @@ Object.defineProperty(that, "remove", { ...@@ -348,9 +352,6 @@ Object.defineProperty(that, "remove", {
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} include_docs Include document metadata * - {boolean} include_docs Include document metadata
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include revisions.
* - {boolean} conflicts Include conflicts.
* @param {function} callback (optional) The callback(err,response). * @param {function} callback (optional) The callback(err,response).
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -373,19 +374,51 @@ Object.defineProperty(that, "allDocs", { ...@@ -373,19 +374,51 @@ Object.defineProperty(that, "allDocs", {
} }
}); });
/**
* Get an attachment from a document.
* @method gettAttachment
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* - {string} _attachment The attachment id
* For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object.defineProperty(that, "getAttachment", {
configurable: false,
enumerable: false,
writable: false,
value: function (doc, options, success, error) {
var param = priv.parametersToObject(
[options, success, error],
{max_retry: 3}
);
priv.addJob(getAttachmentCommand, {
doc: doc,
options: param.options,
callbacks: {success: param.success, error: param.error}
});
}
});
/** /**
* Put an attachment to a document. * Put an attachment to a document.
* @method putAttachment * @method putAttachment
* @param {object} doc The document object. Contains at least: * @param {object} doc The document object. Contains at least:
* - {string} _id The document id: "doc_id/attchment_id" * - {string} _id The document id
* - {string} _data Base64 attachment data * - {string} _attachment The attachment id
* - {string} _data The attachment data
* - {string} _mimetype The attachment mimetype * - {string} _mimetype The attachment mimetype
* - {string} _rev The attachment revision * For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options: * @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity. * - {number} max_retry The number max of retries, 0 = infinity.
* - {boolean} revs Include revision history of the document.
* - {boolean} revs_info Include revisions.
* - {boolean} conflicts Include conflicts.
* @param {function} callback (optional) The callback(err,respons) * @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this * @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success", * callback is given in parameter, "callback" is changed as "success",
...@@ -409,6 +442,39 @@ Object.defineProperty(that, "putAttachment", { ...@@ -409,6 +442,39 @@ Object.defineProperty(that, "putAttachment", {
} }
}); });
/**
* Put an attachment to a document.
* @method putAttachment
* @param {object} doc The document object. Contains at least:
* - {string} _id The document id
* - {string} _attachment The attachment id
* For revision managing:
* - {string} _rev The document revision
* @param {object} options (optional) Contains some options:
* - {number} max_retry The number max of retries, 0 = infinity.
* @param {function} callback (optional) The callback(err,respons)
* @param {function} error (optional) The callback on error, if this
* callback is given in parameter, "callback" is changed as "success",
* called on success.
*/
Object.defineProperty(that, "removeAttachment", {
configurable: false,
enumerable: false,
writable: false,
value: function (doc, options, success, error) {
var param = priv.parametersToObject(
[options, success, error],
{max_retry: 0}
);
priv.addJob(removeAttachmentCommand, {
doc: doc,
options: param.options,
callbacks: {success: param.success, error: param.error}
});
}
});
/** /**
* Check a document. * Check a document.
* @method check * @method check
......
...@@ -372,10 +372,11 @@ test ("All requests ok", function () { ...@@ -372,10 +372,11 @@ test ("All requests ok", function () {
o.tick(o); o.tick(o);
// put an attachment // put an attachment
o.spy(o, "value", {"ok": true, "id": "file/attmt"}, o.spy(o, "value", {"ok": true, "id": "file", "attachment": "attmt"},
"Put attachment"); "Put attachment");
o.jio.putAttachment({ o.jio.putAttachment({
"_id": "file/attmt", "_id": "file",
"_attachment": "attmt",
"_data": "0123456789", "_data": "0123456789",
"_mimetype": "text/plain" "_mimetype": "text/plain"
}, o.f); }, o.f);
...@@ -388,7 +389,7 @@ test ("All requests ok", function () { ...@@ -388,7 +389,7 @@ test ("All requests ok", function () {
// get attachment // get attachment
o.spy(o, "value", "0123456789", "Get attachment"); o.spy(o, "value", "0123456789", "Get attachment");
o.jio.get({"_id": "file/attmt"}, o.f); o.jio.getAttachment({"_id": "file", "_attachment": "attmt"}, o.f);
o.tick(o); o.tick(o);
// remove document // remove document
...@@ -397,8 +398,9 @@ test ("All requests ok", function () { ...@@ -397,8 +398,9 @@ test ("All requests ok", function () {
o.tick(o); o.tick(o);
// remove attachment // remove attachment
o.spy(o, "value", {"ok": true, "id": "file/attmt"}, "Remove attachment"); o.spy(o, "value", {"ok": true, "id": "file", "attachment": "attmt"},
o.jio.remove({"_id": "file/attmt"}, o.f); "Remove attachment");
o.jio.removeAttachment({"_id": "file", "_attachment": "attmt"}, o.f);
o.tick(o); o.tick(o);
// alldocs // alldocs
...@@ -460,7 +462,8 @@ test ("All requests fail", function () { ...@@ -460,7 +462,8 @@ test ("All requests fail", function () {
o.spy(o, "status", 0, o.spy(o, "status", 0,
"Put attachment"); "Put attachment");
o.jio.putAttachment({ o.jio.putAttachment({
"_id": "file/attmt", "_id": "file",
"_attachment": "attmt",
"_data": "0123456789", "_data": "0123456789",
"_mimetype": "text/plain" "_mimetype": "text/plain"
}, o.f); }, o.f);
...@@ -473,7 +476,7 @@ test ("All requests fail", function () { ...@@ -473,7 +476,7 @@ test ("All requests fail", function () {
// get attachment // get attachment
o.spy(o, "status", 0, "Get attachment"); o.spy(o, "status", 0, "Get attachment");
o.jio.get({"_id": "file/attmt"}, o.f); o.jio.get({"_id": "file", "_attachment": "attmt"}, o.f);
o.tick(o); o.tick(o);
// remove document // remove document
...@@ -483,7 +486,7 @@ test ("All requests fail", function () { ...@@ -483,7 +486,7 @@ test ("All requests fail", function () {
// remove attachment // remove attachment
o.spy(o, "status", 0, "Remove attachment"); o.spy(o, "status", 0, "Remove attachment");
o.jio.remove({"_id": "file/attmt"}, o.f); o.jio.remove({"_id": "file", "_attachment": "attmt"}, o.f);
o.tick(o); o.tick(o);
// alldocs // alldocs
...@@ -525,10 +528,11 @@ test ("All document not found", function () { ...@@ -525,10 +528,11 @@ test ("All document not found", function () {
o.tick(o); o.tick(o);
// put an attachment // put an attachment
o.spy(o, "value", {"ok": true, "id": "file/attmt"}, o.spy(o, "value", {"ok": true, "id": "file", "attachment": "attmt"},
"Put attachment"); "Put attachment");
o.jio.putAttachment({ o.jio.putAttachment({
"_id": "file/attmt", "_id": "file",
"_attachment": "attmt",
"_data": "0123456789", "_data": "0123456789",
"_mimetype": "text/plain" "_mimetype": "text/plain"
}, o.f); }, o.f);
...@@ -551,7 +555,7 @@ test ("All document not found", function () { ...@@ -551,7 +555,7 @@ test ("All document not found", function () {
// remove attachment // remove attachment
o.spy(o, "status", 404, "Remove attachment"); o.spy(o, "status", 404, "Remove attachment");
o.jio.remove({"_id": "file/attmt"}, o.f); o.jio.removeAttachment({"_id": "file", "_attachment": "attmt"}, o.f);
o.tick(o); o.tick(o);
o.jio.stop(); o.jio.stop();
...@@ -587,10 +591,11 @@ test ("All document found", function () { ...@@ -587,10 +591,11 @@ test ("All document found", function () {
o.tick(o); o.tick(o);
// put an attachment // put an attachment
o.spy(o, "value", {"ok": true, "id": "file/attmt"}, o.spy(o, "value", {"ok": true, "id": "file", "attachment": "attmt"},
"Put attachment"); "Put attachment");
o.jio.putAttachment({ o.jio.putAttachment({
"_id": "file/attmt", "_id": "file",
"_attachment": "attmt",
"_data": "0123456789", "_data": "0123456789",
"_mimetype": "text/plain" "_mimetype": "text/plain"
}, o.f); }, o.f);
...@@ -603,7 +608,7 @@ test ("All document found", function () { ...@@ -603,7 +608,7 @@ test ("All document found", function () {
// get attachment // get attachment
o.spy(o, "value", "0123456789", "Get attachment"); o.spy(o, "value", "0123456789", "Get attachment");
o.jio.get({"_id": "file/attmt"}, o.f); o.jio.getAttachment({"_id": "file", "_attachment": "attmt"}, o.f);
o.tick(o); o.tick(o);
// remove document // remove document
...@@ -612,8 +617,9 @@ test ("All document found", function () { ...@@ -612,8 +617,9 @@ test ("All document found", function () {
o.tick(o); o.tick(o);
// remove attachment // remove attachment
o.spy(o, "value", {"ok": true, "id": "file/attmt"}, "Remove attachment"); o.spy(o, "value", {"ok": true, "id": "file", "attachment": "attmt"},
o.jio.remove({"_id": "file/attmt"}, o.f); "Remove attachment");
o.jio.removeAttachment({"_id": "file", "_attachment": "attmt"}, o.f);
o.tick(o); o.tick(o);
o.jio.stop(); o.jio.stop();
...@@ -864,7 +870,7 @@ test ("PutAttachment", function(){ ...@@ -864,7 +870,7 @@ test ("PutAttachment", function(){
// putAttachment without document // putAttachment without document
// error 404 -> not found // error 404 -> not found
o.spy(o, "status", 404, "PutAttachment without document"); o.spy(o, "status", 404, "PutAttachment without document");
o.jio.putAttachment({"_id": "putattmt1/putattmt2"}, o.f); o.jio.putAttachment({"_id": "putattmt1", "_attachment": "putattmt2"}, o.f);
o.tick(o); o.tick(o);
// adding a document // adding a document
...@@ -874,9 +880,10 @@ test ("PutAttachment", function(){ ...@@ -874,9 +880,10 @@ test ("PutAttachment", function(){
}); });
// putAttachment with document // putAttachment with document
o.spy(o, "value", {"ok": true, "id": "putattmt1/putattmt2"}, o.spy(o, "value",
{"ok": true, "id": "putattmt1", "attachment": "putattmt2"},
"PutAttachment with document, without data"); "PutAttachment with document, without data");
o.jio.putAttachment({"_id": "putattmt1/putattmt2"}, o.f); o.jio.putAttachment({"_id": "putattmt1", "_attachment": "putattmt2"}, o.f);
o.tick(o); o.tick(o);
// check document // check document
...@@ -904,9 +911,14 @@ test ("PutAttachment", function(){ ...@@ -904,9 +911,14 @@ test ("PutAttachment", function(){
); );
// update attachment // update attachment
o.spy(o, "value", {"ok": true, "id": "putattmt1/putattmt2"}, o.spy(o, "value",
{"ok": true, "id": "putattmt1", "attachment": "putattmt2"},
"Update Attachment, with data"); "Update Attachment, with data");
o.jio.putAttachment({"_id": "putattmt1/putattmt2", "_data": "abc"}, o.f); o.jio.putAttachment({
"_id": "putattmt1",
"_attachment": "putattmt2",
"_data": "abc"
}, o.f);
o.tick(o); o.tick(o);
// check document // check document
...@@ -953,7 +965,7 @@ test ("Get", function(){ ...@@ -953,7 +965,7 @@ test ("Get", function(){
// get inexistent attachment // get inexistent attachment
o.spy(o, "status", 404, "Get inexistent attachment"); o.spy(o, "status", 404, "Get inexistent attachment");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
// adding a document // adding a document
...@@ -970,7 +982,7 @@ test ("Get", function(){ ...@@ -970,7 +982,7 @@ test ("Get", function(){
// get inexistent attachment (document exists) // get inexistent attachment (document exists)
o.spy(o, "status", 404, "Get inexistent attachment (document exists)"); o.spy(o, "status", 404, "Get inexistent attachment (document exists)");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
// adding an attachment // adding an attachment
...@@ -986,7 +998,7 @@ test ("Get", function(){ ...@@ -986,7 +998,7 @@ test ("Get", function(){
// get attachment // get attachment
o.spy(o, "value", "de", "Get attachment"); o.spy(o, "value", "de", "Get attachment");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
o.jio.stop(); o.jio.stop();
...@@ -1008,16 +1020,30 @@ test ("Remove", function(){ ...@@ -1008,16 +1020,30 @@ test ("Remove", function(){
o.jio.remove({"_id": "remove1"}, o.f); o.jio.remove({"_id": "remove1"}, o.f);
o.tick(o); o.tick(o);
// remove inexistent document/attachment // remove inexistent attachment
o.spy(o, "status", 404, "Remove inexistent document/attachment"); o.spy(o, "status", 404, "Remove inexistent attachment");
o.jio.remove({"_id": "remove1/remove2"}, o.f); o.jio.removeAttachment({"_id": "remove1", "_attachment": "remove2"}, o.f);
o.tick(o); o.tick(o);
// adding a document // adding a document + attmt
localstorage.setItem("jio/localstorage/uremove/aremove/remove1", { localstorage.setItem("jio/localstorage/uremove/aremove/remove1", {
"_id": "remove1", "_id": "remove1",
"title": "myRemove1" "title": "myRemove1",
"_attachments": {
"remove2": {
"length": 4,
"digest": "md5-blahblah"
}
}
}); });
localstorage.setItem(
"jio/localstorage/uremove/aremove/remove1/remove2", "fghi");
// remove attachment
o.spy(o, "value", {"ok": true, "id": "remove1", "attachment": "remove2"},
"Remove document");
o.jio.removeAttachment({"_id": "remove1", "_attachment": "remove2"}, o.f);
o.tick(o);
// remove document // remove document
o.spy(o, "value", {"ok": true, "id": "remove1"}, "Remove document"); o.spy(o, "value", {"ok": true, "id": "remove1"}, "Remove document");
...@@ -1043,7 +1069,8 @@ test ("Remove", function(){ ...@@ -1043,7 +1069,8 @@ test ("Remove", function(){
"jio/localstorage/uremove/aremove/remove1/remove2", "fghi"); "jio/localstorage/uremove/aremove/remove1/remove2", "fghi");
// remove attachment // remove attachment
o.spy(o, "value", {"ok": true, "id": "remove1"}, "Remove document and attachment"); o.spy(o, "value", {"ok": true, "id": "remove1"},
"Remove document and attachment");
o.jio.remove({"_id": "remove1"}, o.f); o.jio.remove({"_id": "remove1"}, o.f);
o.tick(o); o.tick(o);
ok(localstorage.getItem("jio/localstorage/uremove/aremove/remove1" ok(localstorage.getItem("jio/localstorage/uremove/aremove/remove1"
...@@ -1656,9 +1683,10 @@ test("Put Attachment", function () { ...@@ -1656,9 +1683,10 @@ test("Put Attachment", function () {
o.rev_hash = generateRevisionHash({"_id": "doc1", "_attachment": "attmt1"}, o.rev_hash = generateRevisionHash({"_id": "doc1", "_attachment": "attmt1"},
o.revisions); o.revisions);
o.rev = "1-" + o.rev_hash; o.rev = "1-" + o.rev_hash;
o.spy(o, "value", {"ok": true, "id": "doc1/attmt1", "rev": o.rev}, o.spy(o, "value",
{"ok": true, "id": "doc1", "attachment": "attmt1", "rev": o.rev},
"PutAttachment without document, without data"); "PutAttachment without document, without data");
o.jio.putAttachment({"_id": "doc1/attmt1"}, o.f); o.jio.putAttachment({"_id": "doc1", "_attachment": "attmt1"}, o.f);
o.tick(o); o.tick(o);
// check document // check document
...@@ -1706,11 +1734,13 @@ test("Put Attachment", function () { ...@@ -1706,11 +1734,13 @@ test("Put Attachment", function () {
"_attachment": "attmt1", "_attachment": "attmt1",
}, o.revisions); }, o.revisions);
o.rev = "2-" + o.rev_hash; o.rev = "2-" + o.rev_hash;
o.spy(o, "value", {"ok": true, "id": "doc1/attmt1", "rev": o.rev}, o.spy(o, "value",
{"ok": true, "id": "doc1", "attachment": "attmt1", "rev": o.rev},
"Update Attachment, with data"); "Update Attachment, with data");
o.jio.putAttachment({ o.jio.putAttachment({
"_id": "doc1/attmt1", "_id": "doc1",
"_data": "abc", "_data": "abc",
"_attachment": "attmt1",
"_rev": o.prev_rev "_rev": o.prev_rev
}, o.f); }, o.f);
o.tick(o); o.tick(o);
...@@ -1752,11 +1782,13 @@ test("Put Attachment", function () { ...@@ -1752,11 +1782,13 @@ test("Put Attachment", function () {
"_attachment": "attmt2", "_attachment": "attmt2",
}, o.revisions); }, o.revisions);
o.rev = "3-" + o.rev_hash; o.rev = "3-" + o.rev_hash;
o.spy(o, "value", {"ok": true, "id": "doc1/attmt2", "rev": o.rev}, o.spy(o, "value",
{"ok": true, "id": "doc1", "attachment": "attmt2", "rev": o.rev},
"PutAttachment without document, without data"); "PutAttachment without document, without data");
o.jio.putAttachment({ o.jio.putAttachment({
"_id": "doc1/attmt2", "_id": "doc1",
"_data": "def", "_data": "def",
"_attachment": "attmt2",
"_rev": o.prev_rev "_rev": o.prev_rev
}, o.f); }, o.f);
o.tick(o); o.tick(o);
...@@ -1820,7 +1852,7 @@ test ("Get", function(){ ...@@ -1820,7 +1852,7 @@ test ("Get", function(){
// get inexistent attachment // get inexistent attachment
o.spy(o, "status", 404, "Get inexistent attachment (winner)" + o.spy(o, "status", 404, "Get inexistent attachment (winner)" +
" -> 404 Not Found"); " -> 404 Not Found");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
// adding a document // adding a document
...@@ -1914,21 +1946,33 @@ test ("Get", function(){ ...@@ -1914,21 +1946,33 @@ test ("Get", function(){
// get attachment winner // get attachment winner
o.spy(o, "value", "abc", "Get attachment (winner)"); o.spy(o, "value", "abc", "Get attachment (winner)");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
// get inexistent attachment specific rev // get inexistent attachment specific rev
o.spy(o, "status", 404, "Get inexistent attachment (specific revision)" + o.spy(o, "status", 404, "Get inexistent attachment (specific revision)" +
" -> 404 Not Found"); " -> 404 Not Found");
o.jio.get({"_id": "get1/get2", "_rev": "1-rev1"}, { o.jio.getAttachment({
"revs_info": true, "revs": true, "conflicts": true, "_id": "get1",
"_attachment": "get2",
"_rev": "1-rev1"
}, {
"revs_info": true,
"revs": true,
"conflicts": true,
}, o.f); }, o.f);
o.tick(o); o.tick(o);
// get attachment specific rev // get attachment specific rev
o.spy(o, "value", "abc", "Get attachment (specific revision)"); o.spy(o, "value", "abc", "Get attachment (specific revision)");
o.jio.get({"_id": "get1/get2", "_rev": "2-rev3"}, { o.jio.getAttachment({
"revs_info": true, "revs": true, "conflicts": true, "_id": "get1",
"_attachment": "get2",
"_rev": "2-rev3"
}, {
"revs_info": true,
"revs": true,
"conflicts": true,
}, o.f); }, o.f);
o.tick(o); o.tick(o);
...@@ -1977,7 +2021,7 @@ test ("Remove", function(){ ...@@ -1977,7 +2021,7 @@ test ("Remove", function(){
// 2. remove attachment without revision // 2. remove attachment without revision
o.spy(o, "status", 409, "Remove attachment without revision " + o.spy(o, "status", 409, "Remove attachment without revision " +
"-> 409 Conflict"); "-> 409 Conflict");
o.jio.remove({"_id":"remove1/remove2"}, o.f); o.jio.removeAttachment({"_id":"remove1", "_attachment": "remove2"}, o.f);
o.tick(o); o.tick(o);
// adding a document with attachments // adding a document with attachments
...@@ -2023,7 +2067,11 @@ test ("Remove", function(){ ...@@ -2023,7 +2067,11 @@ test ("Remove", function(){
// 3. remove inexistent attachment // 3. remove inexistent attachment
o.spy(o, "status", 404, "Remove inexistent attachment -> 404 Not Found"); o.spy(o, "status", 404, "Remove inexistent attachment -> 404 Not Found");
o.jio.remove({"_id": "remove1/remove0", "_rev": "2-oldrev"}, o.f); o.jio.removeAttachment({
"_id": "remove1",
"_attachment": "remove0",
"_rev": "2-oldrev"
}, o.f);
o.tick(o); o.tick(o);
// 4. remove existing attachment // 4. remove existing attachment
...@@ -2031,10 +2079,17 @@ test ("Remove", function(){ ...@@ -2031,10 +2079,17 @@ test ("Remove", function(){
"_id": "remove1", "_id": "remove1",
"_attachment": "remove2", "_attachment": "remove2",
}, {"start": 2, "ids": ["oldrev", "veryoldrev"]}); }, {"start": 2, "ids": ["oldrev", "veryoldrev"]});
o.spy (o, "value", o.spy (o, "value", {
{"ok": true, "id": "remove1/remove2", "rev": "3-" + o.rev_hash}, "ok": true,
"Remove existing attachment"); "id": "remove1",
o.jio.remove({"_id":"remove1/remove2", "_rev": "2-oldrev"}, o.f); "attachment": "remove2",
"rev": "3-" + o.rev_hash
}, "Remove existing attachment");
o.jio.removeAttachment({
"_id": "remove1",
"_attachment": "remove2",
"_rev": "2-oldrev"
}, o.f);
o.tick(o); o.tick(o);
o.doctree = { o.doctree = {
...@@ -2075,7 +2130,11 @@ test ("Remove", function(){ ...@@ -2075,7 +2130,11 @@ test ("Remove", function(){
// 9. remove attachment wrong revision // 9. remove attachment wrong revision
o.spy(o, "status", 409, "Remove attachment with wrong revision " + o.spy(o, "status", 409, "Remove attachment with wrong revision " +
"-> 409 Conflict"); "-> 409 Conflict");
o.jio.remove({"_id":"remove1/remove2", "_rev": "1-a"}, o.f); o.jio.removeAttachment({
"_id": "remove1",
"_attachment": "remove2",
"_rev": "1-a"
}, o.f);
o.tick(o); o.tick(o);
// 10. remove document // 10. remove document
...@@ -2157,7 +2216,7 @@ test ("Scenario", function(){ ...@@ -2157,7 +2216,7 @@ test ("Scenario", function(){
}, o.f); }, o.f);
o.tick(o); o.tick(o);
// MODFIY the 2nd version // MODIFY the 2nd version
o.doc_2 = {"_id": "sample1", "_rev": o.rev, o.doc_2 = {"_id": "sample1", "_rev": o.rev,
"title":"mySample2_modified"}; "title":"mySample2_modified"};
o.revisions_2 = {"start":1 , "ids":[o.hex]}; o.revisions_2 = {"start":1 , "ids":[o.hex]};
...@@ -2168,7 +2227,7 @@ test ("Scenario", function(){ ...@@ -2168,7 +2227,7 @@ test ("Scenario", function(){
o.jio2.put(o.doc_2, o.f); o.jio2.put(o.doc_2, o.f);
o.tick(o); o.tick(o);
// MODFIY first version // MODIFY first version
o.doc_1 = { o.doc_1 = {
"_id": "sample1", "_rev": o.rev, "title": "mySample1_modified" "_id": "sample1", "_rev": o.rev, "title": "mySample1_modified"
}; };
...@@ -2510,10 +2569,9 @@ module ("JIO Replicate Revision Storage"); ...@@ -2510,10 +2569,9 @@ module ("JIO Replicate Revision Storage");
}; };
o.rev_hash = generateRevisionHash(o.doc, {"start": 0, "ids": []}); o.rev_hash = generateRevisionHash(o.doc, {"start": 0, "ids": []});
o.rev = "1-" + o.rev_hash; o.rev = "1-" + o.rev_hash;
o.spy(o, "value", {"ok": true, "id": "doc2/attachment1", "rev": o.rev}, o.spy(o, "value",
{"ok": true, "id": "doc2", "attachment": "attachment1", "rev": o.rev},
"Put an attachment to an inexistent document"); "Put an attachment to an inexistent document");
o.doc._id += "/" + o.doc._attachment;
delete o.doc._attachment;
o.jio.putAttachment(o.doc, o.f); o.jio.putAttachment(o.doc, o.f);
o.tick(o); o.tick(o);
...@@ -2532,10 +2590,12 @@ module ("JIO Replicate Revision Storage"); ...@@ -2532,10 +2590,12 @@ module ("JIO Replicate Revision Storage");
o.rev3_6_history.ids.unshift(o.rev3_6_hash); o.rev3_6_history.ids.unshift(o.rev3_6_hash);
o.rev3_6_revs_info = clone(o.rev2_5_revs_info); o.rev3_6_revs_info = clone(o.rev2_5_revs_info);
o.rev3_6_revs_info.unshift({"rev": o.rev3_6, "status": "available"}); o.rev3_6_revs_info.unshift({"rev": o.rev3_6, "status": "available"});
o.spy(o, "value", {"ok": true, "id": "doc1/attachment1", "rev": o.rev3_6}, o.spy(o, "value", {
"Put an attachment to the first document"); "ok": true,
o.doc._id += "/" + o.doc._attachment; "id": "doc1",
delete o.doc._attachment; "attachment": "attachment1",
"rev": o.rev3_6
}, "Put an attachment to the first document");
o.jio.putAttachment(o.doc, o.f); o.jio.putAttachment(o.doc, o.f);
o.tick(o); o.tick(o);
...@@ -2577,9 +2637,7 @@ module ("JIO Replicate Revision Storage"); ...@@ -2577,9 +2637,7 @@ module ("JIO Replicate Revision Storage");
"_attachment": "attachment1" "_attachment": "attachment1"
}; };
o.spy(o, "value", "doc 1 - attachment 1", "Get the winner's attachment"); o.spy(o, "value", "doc 1 - attachment 1", "Get the winner's attachment");
o.doc._id += "/" + o.doc._attachment; o.jio.getAttachment(o.doc, o.f);
delete o.doc._attachment;
o.jio.get(o.doc, o.f);
o.tick(o); o.tick(o);
// put document // put document
...@@ -2642,9 +2700,7 @@ module ("JIO Replicate Revision Storage"); ...@@ -2642,9 +2700,7 @@ module ("JIO Replicate Revision Storage");
}; };
o.spy(o, "value", "doc 1 - attachment 1", o.spy(o, "value", "doc 1 - attachment 1",
"Get the winner's attachment again"); "Get the winner's attachment again");
o.doc._id += "/" + o.doc._attachment; o.jio.getAttachment(o.doc, o.f);
delete o.doc._attachment;
o.jio.get(o.doc, o.f);
o.tick(o); o.tick(o);
// remove attachment // remove attachment
...@@ -2660,11 +2716,13 @@ module ("JIO Replicate Revision Storage"); ...@@ -2660,11 +2716,13 @@ module ("JIO Replicate Revision Storage");
o.rev5_8_history.ids.unshift(o.rev5_8_hash); o.rev5_8_history.ids.unshift(o.rev5_8_hash);
o.rev5_8_revs_info = clone(o.rev4_7_revs_info); o.rev5_8_revs_info = clone(o.rev4_7_revs_info);
o.rev5_8_revs_info.unshift({"rev": o.rev5_8, "status": "available"}); o.rev5_8_revs_info.unshift({"rev": o.rev5_8, "status": "available"});
o.spy(o, "value", {"ok": true, "id": "doc1/attachment1", "rev": o.rev5_8}, o.spy(o, "value", {
"Remove attachment"); "ok": true,
o.doc._id += "/" + o.doc._attachment; "id": "doc1",
delete o.doc._attachment; "attachment": "attachment1",
o.jio.remove(o.doc, o.f); "rev": o.rev5_8
}, "Remove attachment");
o.jio.removeAttachment(o.doc, o.f);
o.tick(o); o.tick(o);
...@@ -2735,11 +2793,8 @@ module ("JIO Replicate Revision Storage"); ...@@ -2735,11 +2793,8 @@ module ("JIO Replicate Revision Storage");
"_attachment": "attachment1", "_attachment": "attachment1",
"_rev": o.rev3_6 "_rev": o.rev3_6
}; };
o.spy(o, "value", "doc 1 - attachment 1", o.spy(o, "value", "doc 1 - attachment 1", "Get a specific attachment");
"Get a specific attachment"); o.jio.getAttachment(o.doc, o.f);
o.doc._id += "/" + o.doc._attachment;
delete o.doc._attachment;
o.jio.get(o.doc, o.f);
o.tick(o); o.tick(o);
// remove specific document and conflict // remove specific document and conflict
...@@ -4058,7 +4113,7 @@ test ("PutAttachment", function(){ ...@@ -4058,7 +4113,7 @@ test ("PutAttachment", function(){
// putAttachment without document // putAttachment without document
// error 404 -> not found // error 404 -> not found
o.spy(o, "status", 404, "PutAttachment without document"); o.spy(o, "status", 404, "PutAttachment without document");
o.jio.putAttachment({"_id": "putattmt1/putattmt2"}, o.f); o.jio.putAttachment({"_id": "putattmt1", "_attachment": "putattmt2"}, o.f);
o.tick(o); o.tick(o);
// putAttachment with document // putAttachment with document
...@@ -4068,9 +4123,10 @@ test ("PutAttachment", function(){ ...@@ -4068,9 +4123,10 @@ test ("PutAttachment", function(){
o.jio.put(o.doc, o.f); o.jio.put(o.doc, o.f);
o.tick(o); o.tick(o);
o.spy(o, "value", {"ok": true, "id": "putattmt1/putattmt2"}, o.spy(o, "value",
{"ok": true, "id": "putattmt1", "attachment": "putattmt2"},
"PutAttachment with document, without data"); "PutAttachment with document, without data");
o.jio.putAttachment({"_id": "putattmt1/putattmt2"}, o.f); o.jio.putAttachment({"_id": "putattmt1", "_attachment": "putattmt2"}, o.f);
o.tick(o); o.tick(o);
// check document // check document
...@@ -4098,9 +4154,14 @@ test ("PutAttachment", function(){ ...@@ -4098,9 +4154,14 @@ test ("PutAttachment", function(){
); );
// update attachment // update attachment
o.spy(o, "value", {"ok": true, "id": "putattmt1/putattmt2"}, o.spy(o, "value",
{"ok": true, "id": "putattmt1", "attachment": "putattmt2"},
"Update Attachment, with data"); "Update Attachment, with data");
o.jio.putAttachment({"_id": "putattmt1/putattmt2", "_data": "abc"}, o.f); o.jio.putAttachment({
"_id": "putattmt1",
"_attachment": "putattmt2",
"_data": "abc"
}, o.f);
o.tick(o); o.tick(o);
// check document // check document
...@@ -4161,7 +4222,7 @@ test ("Get", function(){ ...@@ -4161,7 +4222,7 @@ test ("Get", function(){
// get inexistent attachment // get inexistent attachment
o.spy(o, "status", 404, "Get inexistent attachment"); o.spy(o, "status", 404, "Get inexistent attachment");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
// adding a document // adding a document
...@@ -4178,7 +4239,7 @@ test ("Get", function(){ ...@@ -4178,7 +4239,7 @@ test ("Get", function(){
// get inexistent attachment (document exists) // get inexistent attachment (document exists)
o.spy(o, "status", 404, "Get inexistent attachment (document exists)"); o.spy(o, "status", 404, "Get inexistent attachment (document exists)");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
// adding an attachment // adding an attachment
...@@ -4194,7 +4255,7 @@ test ("Get", function(){ ...@@ -4194,7 +4255,7 @@ test ("Get", function(){
// get attachment // get attachment
o.spy(o, "value", "de", "Get attachment"); o.spy(o, "value", "de", "Get attachment");
o.jio.get({"_id": "get1/get2"}, o.f); o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o); o.tick(o);
o.jio.stop(); o.jio.stop();
...@@ -4230,8 +4291,8 @@ test ("Remove", function(){ ...@@ -4230,8 +4291,8 @@ test ("Remove", function(){
o.tick(o); o.tick(o);
// remove inexistent document/attachment // remove inexistent document/attachment
o.spy(o, "status", 404, "Remove inexistent document/attachment"); o.spy(o, "status", 404, "Remove inexistent attachment");
o.jio.remove({"_id": "remove1/remove2"}, o.f); o.jio.removeAttachment({"_id": "remove1", "_attachment": "remove2"}, o.f);
o.tick(o); o.tick(o);
// adding a document // adding a document
...@@ -4288,19 +4349,26 @@ test ("Remove", function(){ ...@@ -4288,19 +4349,26 @@ test ("Remove", function(){
o.tick(o); o.tick(o);
// adding an attachment // adding an attachment
o.jio.putAttachment({"_id":"remove3/removeAtt", "_mimetype":"text/plain", o.jio.putAttachment({
"_data":"hello"}); "_id": "remove3",
"_attachment": "removeAtt",
"_mimetype": "text/plain",
"_data": "hello"});
o.tick(o); o.tick(o);
// add another attachment // add another attachment
o.jio.putAttachment({"_id":"remove3/removeAtt2", "_mimetype":"text/plain", o.jio.putAttachment({
"_data":"hello2"}); "_id": "remove3",
"_attachment": "removeAtt2",
"_mimetype": "text/plain",
"_data": "hello2"});
o.tick(o); o.tick(o);
// remove attachment // remove attachment
o.spy(o, "value", {"ok": true, "id": "remove3/removeAtt2"}, o.spy(o, "value", {"ok": true, "id": "remove3", "attachment": "removeAtt2"},
"Remove one of multiple attachment"); "Remove one of multiple attachment");
o.jio.remove({"_id": "remove3/removeAtt2"}, o.f); o.jio.removeAttachment({"_id": "remove3", "_attachment": "removeAtt2"},
o.f);
o.tick(o); o.tick(o);
// check index // check index
...@@ -4360,7 +4428,7 @@ test ("Remove", function(){ ...@@ -4360,7 +4428,7 @@ test ("Remove", function(){
// check attachment // check attachment
o.spy(o, "status", 404, "Check if attachment has been removed"); o.spy(o, "status", 404, "Check if attachment has been removed");
o.jio.get({"_id": "remove3/removeAtt"}, o.f); o.jio.getAttachment({"_id": "remove3", "_attachment": "removeAtt"}, o.f);
o.tick(o); o.tick(o);
// check document // check document
......
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