Commit 90d37ed6 authored by Sven Franck's avatar Sven Franck

PUTATTACHEMENT working, removed methods to util

parent eca94a2a
......@@ -19,14 +19,14 @@ var utilities = {
isObjectEmpty : function(obj) {
var key;
if (obj.length && obj.length > 0){
if (obj.length && obj.length > 0) {
return false;
}
if (obj.length && obj.length === 0){
if (obj.length && obj.length === 0) {
return true;
}
for (key in obj) {
if ({}.hasOwnProperty.call(obj, key)){
if ({}.hasOwnProperty.call(obj, key)) {
return false;
}
}
......@@ -41,7 +41,7 @@ var utilities = {
isObjectSize : function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)){
if (obj.hasOwnProperty(key)) {
size++;
}
}
......@@ -54,11 +54,11 @@ var utilities = {
* @param {haystack} array - active leaves (versions of a document)
* @returns {boolean} string- true/false
*/
isInObject : function (needle, haystack){
isInObject : function (needle, haystack) {
var length = haystack.length;
for(var i = 0; i < length; i++) {
if(haystack[i] === needle){
if(haystack[i] === needle) {
return true;
}
}
......@@ -70,7 +70,7 @@ var utilities = {
* @param {needle} string - docId
* @returns {boolean} string- true/false
*/
isUUID : function (documentId){
isUUID : function (documentId) {
var reg = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test( documentId );
return reg;
},
......@@ -81,10 +81,10 @@ var utilities = {
* @param {reason} string - the error reason
* @returns {e} object - error object
*/
throwError : function ( code, reason ) {
throwError : function (code, reason) {
var statusText, error, message, errorObject;
switch( code ){
switch(code) {
case 409:
statusText = 'Conflict';
......@@ -195,7 +195,7 @@ var utilities = {
* @stored - 'jio/local/USR/APP/FILE_NAME'
* @returns {doc} object - document object
*/
createDocument : function (docId, docPath){
createDocument : function (docId, docPath) {
var now = Date.now(),
doc = {},
hash = utilities.hashCode('' + doc + ' ' + now + '');
......@@ -221,13 +221,31 @@ var utilities = {
* @param {docid} string - id for the new document
* @param {docpath} string - the path where to store the document
* @param {previousRevision} string - the previous revision
* @param {attachmentId} - string - in case attachments are handled
* @returns {doc} object - new document
*/
updateDocument : function (doc, docPath, previousRevision){
updateDocument : function (doc, docPath, previousRevision, attachmentId) {
var now = Date.now(),
rev = utilities.generateNextRevision(previousRevision, ''+
doc+' '+now+'');
// in case the update is made because of an attachment
if (attachmentId !== undefined) {
// create _attachments
if (doc._attachments === undefined){
doc._attachments = {};
}
// create _attachments object for this attachment
if (doc._attachments[attachmentId] === undefined){
doc._attachments[attachmentId] = {};
}
// set revpos
doc._attachments[attachmentId].revpos =
parseInt(doc._rev.split('-')[0],10);
}
// update document
doc._rev = rev.join('-');
doc._revisions.ids.unshift(rev[1]);
......@@ -237,7 +255,6 @@ var utilities = {
"rev": rev.join('-'),
"status": "available"
});
return doc;
},
......@@ -255,14 +272,13 @@ var utilities = {
* @info - deleted versions/branches = "status deleted"
* @info - no active leaves will delete tree, too
*/
createDocumentTree : function (doc){
createDocumentTree : function(doc) {
var tree = {
type:'leaf',
status:'available',
rev:doc._rev,
kids:[]
};
return tree;
},
......@@ -273,50 +289,57 @@ var utilities = {
* @param {new_rev } string - revison of the tree node to add as leaf
* @param {revs_info} object- history of new_rev to merge with remote tree
*/
updateDocumentTree : function ( docTreeNode, old_rev, new_rev, revs_info ){
if ( typeof revs_info === "object" ){
updateDocumentTree : function (docTreeNode, old_rev, new_rev,
revs_info, deletedLeaf ) {
if (typeof revs_info === "object") {
// a new document version is being stored from another storage
utilities.mergeRemoteTree( docTreeNode, docTreeNode, old_rev, new_rev,
revs_info, [], false );
utilities.mergeRemoteTree(docTreeNode, docTreeNode, old_rev, new_rev,
revs_info, [], false, deletedLeaf);
} else {
// update an existing version of document = add a node to the tree
utilities.setTreeNode( docTreeNode, old_rev, new_rev );
utilities.setTreeNode(docTreeNode, old_rev, new_rev, 'available');
}
return docTreeNode;
},
// ==================== SET/MERGE/CHECK TREE NODES ==================
/**
* @method setTreeNode - adds a new tree node/changes leaf to branch
* @method setTreeNode - adds a new tree node/changes leaf to branch
* @param {docTreeNode} object - document tree
* @param {old_rev} string - revision of the tree node to set to "branch"
* @param {new_rev } string - revison of the tree node to add as leaf
* @param {old_rev} string - revision of the tree node to set to "branch"
* @param {new_rev } string - revison of the tree node to add as leaf
* @param {new_status}string- status the new node should have
* @info - status is necessary, because we may also
* add deleted nodes to the tree from a
* remote storage
*/
setTreeNode : function (docTreeNode, old_rev, new_rev){
setTreeNode : function (docTreeNode, old_rev, new_rev, new_status){
var kids = docTreeNode['kids'],
rev = docTreeNode['rev'],
numberOfKids,
i,
key;
for( key in docTreeNode ){
if ( key === "rev" ){
for(key in docTreeNode){
if (key === "rev"){
// grow the tree
if ( old_rev === rev && new_rev !== rev ){
if (old_rev === rev && new_rev !== rev) {
docTreeNode.type = 'branch';
docTreeNode.status = 'deleted';
docTreeNode.kids.push({
type:'leaf',
status: 'available',
status:new_status,
rev:new_rev,
kids:[]
});
} else {
// traverse until correct node is found!
if ( utilities.isObjectEmpty( kids ) === false ){
if ( utilities.isObjectEmpty( kids ) === false ) {
numberOfKids = utilities.isObjectSize(kids);
for ( i = 0; i < numberOfKids; i+=1 ){
utilities.setTreeNode(kids[i], old_rev, new_rev);
utilities.setTreeNode(kids[i], old_rev, new_rev, new_status);
}
}
}
......@@ -337,30 +360,29 @@ var utilities = {
* for the new tree node (we are copy&pasting
* from another storage)
*/
mergeRemoteTree : function ( initialTree, docTreeNode, old_rev, new_rev,
newDocumentRevisions, addNodes, onTree ){
mergeRemoteTree : function (initialTree, docTreeNode, old_rev, new_rev,
newDocumentRevisions, addNodes, onTree, deletedLeaf){
var sync_rev = newDocumentRevisions[0].rev,
current_tree_rev = docTreeNode['rev'],
kids = docTreeNode['kids'],
nodeStatus = 'available',
addNodesLen,
numberOfKids,
key,
i,
j;
for ( key in docTreeNode ){
if ( key === "rev" ){
for (key in docTreeNode) {
if (key === "rev") {
// commeon ancestor? = does the revision on the current
// common ancestor? = does the revision on the current
// tree node match the currently checked remote tree
// revision
// match = common ancestor
if ( sync_rev === current_tree_rev ){
if (sync_rev === current_tree_rev){
onTree = true;
// in order to loop we also add the revision of
// the common ancestor node to the array
// using push!
......@@ -370,19 +392,20 @@ var utilities = {
// the addNodes array will now look like this
// [current_node, all_missing_nodes]
for ( j = 0; j < addNodesLen; j+=1 ){
utilities.setTreeNode( initialTree, addNodes[j],
addNodes[j+1]
);
for (j = 0; j < addNodesLen; j+=1){
// last node being added is deleted
if (deletedLeaf === true && j === addNodesLen-1){
nodeStatus = 'deleted';
}
utilities.setTreeNode(initialTree, addNodes[j],
addNodes[j+1], nodeStatus);
}
// no match = continue down the tree
} else if ( utilities.isObjectEmpty( kids ) === false ){
numberOfKids = utilities.isObjectSize( kids );
for ( i = 0; i < numberOfKids; i+=1 ){
utilities.mergeRemoteTree( initialTree, kids[i], old_rev, new_rev,
newDocumentRevisions, addNodes, onTree );
newDocumentRevisions, addNodes, onTree, deletedLeaf );
}
// end of tree = start over checking the next remote revision
......@@ -403,13 +426,22 @@ var utilities = {
// this should start over with the full document tree
// otherwise it will only continue on the current (last) node
utilities.mergeRemoteTree( initialTree, initialTree, old_rev, new_rev,
newDocumentRevisions, addNodes, onTree );
newDocumentRevisions, addNodes, onTree, deletedLeaf );
}
}
}
return docTreeNode;
},
getActiveLeaves : function (docTreeNode) {
var activeLeaves = utilities.getLeavesOnTree( docTreeNode );
activeLeaves = typeof activeLeaves === "string" ?
[activeLeaves] : activeLeaves;
return activeLeaves;
},
/**
* @method getLeavesOnTree - finds all leaves on a tree
* @param {docTree} string - the tree for this document
......@@ -461,7 +493,10 @@ var utilities = {
status = docTreeNode['status'],
kids = docTreeNode['kids'],
rev = docTreeNode['rev'],
result = false, numberOfKids,i,key;
result = false,
numberOfKids,
i,
key;
for ( key in docTreeNode ){
if ( key === "rev" ){
......@@ -470,8 +505,7 @@ var utilities = {
( type === 'branch' || status === 'deleted' ) ){
result = true;
}
if ( typeof kids === "object" &&
utilities.isObjectEmpty( kids ) === false ){
if ( utilities.isObjectEmpty( kids ) === false ){
numberOfKids = utilities.isObjectSize( kids );
for ( i = 0; i < numberOfKids; i+=1 ){
......
......@@ -165,9 +165,102 @@ var newLocalStorage = function ( spec, my ) {
};
/**
* @method post
*
* Create a document in local storage.
* runDocumentUpdate - run the whole update process for localstorage
* @param {object} doc - the original document object.
* @param {object} docTree - the document tree
* @param {object} command - command object
* @param {string} docId - document id
* @param {string} attachmentId - attachmentId
* @param {string} docPath - document paths
* @param {string} prev_rev- previous revision
* @param {string} treePath- document tree paths
* @param {boolean} sync - whether this is an update or sync operation!
* @returns {object} success- success object
*/
priv.runDocumentUpdate = function ( doc, docTree, command, docId, attachmentId,
docPath, prev_rev, treePath, sync ){
var docPathRev,
newRevision,
revs_info,
deletedLeaf;
// update ...I don't know what this is doing?
priv.documentObjectUpdate(doc,command.cloneDoc());
// update document - not when put sync-ing
if ( sync === false ){
// create a new revision
doc = utilities.updateDocument(doc, docPath, prev_rev, attachmentId);
docPathRev = docPath+'/'+doc._rev;
newRevision = doc._rev;
revs_info = undefined;
// delete old doc (.../DOCID/old_REVISION)
localstorage.deleteItem(docPath+'/'+prev_rev);
} else {
docPathRev = docPath +'/'+doc._revs_info[0].rev;
newRevision = null;
revs_info = doc._revs_info;
if ( revs_info[0].status === 'deleted' ){
deletedLeaf = true;
}
}
if ( deletedLeaf === undefined ){
// store new doc (.../DOCID/new_REVISION)
localstorage.setItem(docPathRev, doc);
}
// update tree and store
localstorage.setItem(treePath, utilities.updateDocumentTree(
docTree, prev_rev, newRevision,
revs_info, deletedLeaf)
);
// return SUCCESS
return priv.manageOptions({ok:true,id:docId,rev:doc._rev}, command, doc);
};
/**
* runDocumentCreate - run the whole create process for localstorage
* @param {string} docId - document id
* @param {object} command - command object
* @returns {object} success- success object
*/
priv.runDocumenCreate = function (docId, command){
// create new document and tree
var docPath = 'jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname+'/'+docId,
doc = utilities.createDocument( docId, docPath ),
tree = utilities.createDocumentTree( doc ),
treePath = docPath+'/revision_tree';
// store document
localstorage.setItem(docPath + '/' + doc._rev, doc);
// store tree
localstorage.setItem(treePath, tree);
// add user
if (!priv.doesUserExist(priv.secured_username)) {
priv.addUser(priv.secured_username);
}
// add fileName
priv.addFileName(docId);
// return SUCCESS
return priv.manageOptions({ok:true,id:docId,rev:doc._rev}, command, doc);
};
// =============================== METHODS ======================
/**
* @method post - Create a document in local storage.
* @stored - 'jio/local/USR/APP/FILE_NAME/REVISION'.
*
* Available options:
* - {boolean} conflicts - Add a conflicts object to the response
......@@ -178,17 +271,10 @@ var newLocalStorage = function ( spec, my ) {
that.post = function (command) {
setTimeout (function () {
var doc,
docId = command.getDocId(),
docPath = 'jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname+'/'+docId,
tree,
treePath = docPath+'/revision_tree',
docTree = localstorage.getItem(treePath),
var docId = command.getDocId(),
reg = utilities.isUUID(docId);
// no attachments allowed
// 403 - no attachments allowed
if (command.getAttachmentId()) {
that.error( utilities.throwError( 403,
'Attachment cannot be added with a POST request')
......@@ -196,50 +282,25 @@ var newLocalStorage = function ( spec, my ) {
return;
}
if ( reg !== true ) {
// id was supplied, use PUT
// 403 id was supplied, use PUT
if (reg !== true) {
that.error( utilities.throwError( 403,
'ID cannot be supplied with a POST request. Please use PUT')
);
return;
// ok
} else {
// create new document
doc = utilities.createDocument( docId, docPath );
// store
localstorage.setItem(docPath + '/' + doc._rev, doc);
// create and store new document.tree
tree = utilities.createDocumentTree( doc );
// store
localstorage.setItem(treePath, tree);
// add user
if (!priv.doesUserExist (priv.secured_username)) {
priv.addUser (priv.secured_username);
}
// add fileName
priv.addFileName(docId);
that.success (
priv.manageOptions(
{ok:true,id:docId,rev:doc._rev},
command,
doc
)
that.success(
priv.runDocumenCreate(docId, command)
);
}
});
}; // end post
};
/**
* @method put
*
* Create or Update a document in local storage.
* @method put - Create or Update a document in local storage.
* @stored - 'jio/local/USR/APP/FILE_NAME/REVISION'.
*
* Available options:
* - {boolean} conflicts - Add a conflicts object to the response
......@@ -254,14 +315,17 @@ var newLocalStorage = function ( spec, my ) {
prev_rev = command.getDocInfo('_rev'),
docPath ='jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname+'/'+docId,
treePath = docPath+'/revision_tree',tree,
treePath = docPath+'/revision_tree',
docTree = localstorage.getItem(treePath),
doc, docPathRev, activeLeaves, reg = utilities.isUUID(docId), newDocTree;
doc,
docPathRev,
activeLeaves,
reg = utilities.isUUID(docId);
// no tree = create document or error
if (!docTree) {
// id/revision provided = update, revision must be incorrect
// 404 id/revision provided = update, incorrect revision
if ( prev_rev !== undefined && reg === false ){
that.error( utilities.throwError( 404,
'Document not found, please check revision and/or ID')
......@@ -269,7 +333,7 @@ var newLocalStorage = function ( spec, my ) {
return;
}
// no revision and UUID = create, no id provided
// 409 no revision and UUID = create, no id provided
if ( prev_rev === undefined && reg === true){
that.error( utilities.throwError( 409,
'Missing Document ID and or Revision')
......@@ -278,238 +342,179 @@ var newLocalStorage = function ( spec, my ) {
}
// if passed here, we create.
// it could be create (id+content) or update (without revision)
// but since no tree was found and the tree includes id only
// we only end here with a NEW id, so update sans revision cannot
// be the case.
// it could be create (id+content) or update (sans revision)
// but since no tree was found we end here with a NEW id only
// (otherwise tree would be have been found).
that.success(
priv.runDocumenCreate(docId, command)
);
// create and store new document
doc = utilities.createDocument( docId, docPath );
} else {
// found a tree
activeLeaves = utilities.getActiveLeaves( docTree );
// store
localstorage.setItem(docPath + '/' + doc._rev, doc);
// check if revision is on doc-tree and if it is an active leaf
if ( !utilities.isInObject( prev_rev, activeLeaves ) ) {
// create and store new document.tree
tree = utilities.createDocumentTree( doc );
// check if it's a dead leaf (wrong revision)
if ( utilities.isDeadLeaf( prev_rev, docTree ) ){
// 409 deleted leaf/branch = wrong revision
that.error( utilities.throwError( 409,
'Revision supplied is not the latest revision')
);
return;
}
// store
localstorage.setItem(treePath, tree);
// maybe a sync-PUT from another storage, we must
// have revs_info option, otherwise we cannot know
// where to put the file and update the storage tree
if ( !utilities.isDeadLeaf( prev_rev, docTree ) &&
command.getDocInfo('_revs_info') === undefined ){
// add user
if (!priv.doesUserExist (priv.secured_username)) {
priv.addUser (priv.secured_username);
// 409 no revs_info provided
that.error( utilities.throwError( 409,
'Missing revs_info required for sync-put')
);
return;
} else {
// SYNC PUT
// revs_info is provided, this is a new version
// store this document and merge
// NOTE: we also have to SYNC PUT deleted versions
// otherwise the tree will not be the same AND
// other storages will not know which versions of a
// document have been deleted!!!!
// get the new document
doc = command.getDoc();
// ok
that.success(
priv.runDocumentUpdate(doc, docTree, command,
docId, undefined, docPath, prev_rev,
treePath, true)
);
}
} else {
// revision matches a currently active leaf
// = update of an existing document version
// get doc
docPathRev = docPath +'/'+prev_rev;
doc = localstorage.getItem(docPathRev);
if (!doc ){
// 404 document not available, should not happen!
that.error( utilities.throwError( 404,
'Referenced document not found')
);
return;
} else {
// ok
that.success(
priv.runDocumentUpdate(doc, docTree, command,
docId, undefined, docPath, prev_rev,
treePath, false)
);
}
}
}
});
};
/**
* @method putAttachment - Saves/updates an attachment of a document
* @stored at - 'jio/local/USR/APP/FILE_NAME/REVISION/ATTACHMENTID'.
*
* Available options:
* - {boolean} conflicts - Add a conflicts object to the response
* - {boolean} revs - Add the revisions history of the document
* - {boolean} revs_info - Add revisions informations
*/
that.putAttachment = function (command) {
setTimeout( function () {
var docId = command.getDocId(),
docPath ='jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname+'/'+docId,
prev_rev = command.getDocInfo('_rev'),
treePath = docPath+'/revision_tree',
docTree = localstorage.getItem(treePath),
doc,
docPathRev,
activeLeaves,
attachmentId,
attachment,
attachmentPath;
// add fileName
priv.addFileName(docId);
if (!docTree) {
that.success (
priv.manageOptions(
{ok:true,id:docId,rev:doc._rev},
command,
doc
)
// 404 document wasn't found = wrong id or revision
that.error( utilities.throwError( 404,
'Document not found, please check document ID')
);
return;
} else {
// found a tree - get active leaves
activeLeaves = utilities.getLeavesOnTree( docTree );
// found a tree
activeLeaves = utilities.getActiveLeaves( docTree );
// this should return an array of all active leaves
// or a single leaf, which needs to be put into an array
activeLeaves = typeof activeLeaves === "string" ?
[activeLeaves] : activeLeaves;
// check if revision is on doc-tree and is an active leaf
if ( !utilities.isInObject( prev_rev, activeLeaves ) ) {
// check if it's a branch/dead leaf (deleted/updated version)
if ( utilities.isDeadLeaf( prev_rev, docTree ) ){
that.error( utilities.throwError( 409,
'Revision supplied is not the latest revision')
);
return;
}
// check if revision is on tree
if ( utilities.isInObject( prev_rev, activeLeaves ) ) {
// maybe a sync-PUT from another storage, we must
// have revs_info option, otherwise we cannot know
// where to put the file and update the storage tree
if ( !utilities.isDeadLeaf( prev_rev, docTree ) &&
command.getDocInfo('_revs_info') === undefined ){
that.error( utilities.throwError( 409,
'Missing revs_info required for sync-put')
);
return;
} else {
// SYNC PUT
// revs_info is provided, this is a new version
// store this document and merge
// get the new document
doc = command.getDoc();
// we are not updating, this is a copy&paste sync
// therefore the path should have the revision of
// the current document. No new revision hash
// needs to be created
docPathRev = docPath +'/'+doc._revs_info[0].rev;
// update ...???
priv.documentObjectUpdate(doc,command.cloneDoc());
// store the new item.
localstorage.setItem( docPathRev, doc );
// update tree and store
localstorage.setItem(treePath,
utilities.updateDocumentTree( docTree, prev_rev, null,
doc._revs_info )
);
that.success (
priv.manageOptions(
{ok:true,id:docId,rev:prev_rev},
command,
doc
)
);
}
} else {
// check if dead leaf
if ( utilities.isDeadLeaf( prev_rev, docTree ) ){
// revision matches a currently active leaf
// update of an existing document version
// 409 deleted leaf/branch = wrong revision
that.error( utilities.throwError( 409,
'Trying to update on a previous document version')
);
return;
// get doc
docPathRev = docPath +'/'+prev_rev;
doc = localstorage.getItem(docPathRev);
} else {
// revision is ok
attachmentId = command.getAttachmentId();
if (!doc ){
// documen not available, should not happen!
that.error( utilities.throwError( 404,
'Referenced document not found')
// 409 missing attachment id
if ( !attachmentId ){
that.error( utilities.throwError( 409,
'No attachment id specified')
);
return;
} else {
// update ...?
priv.documentObjectUpdate(doc,command.cloneDoc());
// update document
doc = utilities.updateDocument( doc, docPath, prev_rev );
// store new doc (.../DOCID/new_REVISION)
localstorage.setItem(docPath+'/'+doc._rev, doc);
// delete old doc (.../DOCID/old_REVISION)
localstorage.deleteItem(docPath+'/'+prev_rev);
// update tree and store
localstorage.setItem(treePath,
utilities.updateDocumentTree(
docTree, prev_rev, doc._rev, undefined )
);
that.success (
priv.manageOptions(
{ok:true,id:docId,rev:doc._rev},
command,
doc
)
// set attachment
attachmentPath = docPath+'/'+prev_rev+'/'+attachmentId;
attachment = localstorage.getItem(attachmentPath);
// store/update attachment
localstorage.setItem(attachmentPath,command.getContent());
// get doc
docPathRev = docPath +'/'+prev_rev;
doc = localstorage.getItem(docPathRev);
// ok
that.success(
priv.runDocumentUpdate(doc, docTree, command,
docId, attachmentId, docPath, prev_rev,
treePath, false)
);
} // found a doc to update
} // updating existing document
} // found a tree
}); // set timeout
}; // end put
/**
* Saves/updates an attachment of a specified document.
* attachment will be stored @ 'jio/local/USR/APP/FILE_NAME/ATTACHMENTID'.
* @method putAttachment
*/
that.putAttachment = function (command) {
var now = Date.now();
// wait a little in order to simulate asynchronous saving
setTimeout (function () {
var docid, doc, docpath, attmtid, attmt, attmtpath, prev_rev, rev;
docid = command.getDocId();
prev_rev = command.getDocInfo('_rev');
docpath ='jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname+'/'+docid;
// 404
doc = localstorage.getItem(docpath);
if (!doc) {
that.error({
status:404,statusText:'Not found',error:'not_found',
message:'Document not found.',
reason:'Document with specified id does not exist'
});
return;
}
// 409
if (doc._rev !== prev_rev) {
// want to update an older document
that.error({
status:409,statusText:'Conflict',error:'conflict',
message:'Document update conflict.',
reason:'Trying to update a previous document version'
});
return;
}
// check attachment id
attmtid = command.getAttachmentId();
if (attmtid) {
attmtpath = docpath+'/'+attmtid;
attmt = localstorage.getItem(attmtpath);
// create _attachments
if ( doc._attachments === undefined ){
doc._attachments = {};
}
}
}
// create _attachments object for this attachment
if ( doc._attachments[attmtid] === undefined ){
doc._attachments[attmtid] = {};
} else {
// 404 revision supplied is not on tree
that.error( utilities.throwError( 404,
'Document not found, please check revision')
);
return;
}
// set revpos
doc._attachments[attmtid].revpos =
parseInt(doc._rev.split('-')[0],10);
// store/update attachment
localstorage.setItem(attmtpath,command.getContent());
} else {
// no attachment id specified
that.error({
status:409,statusText:'Conflict',error:'conflict',
message:'Document update conflict.',
reason:'No attachment id specified'
});
return;
}
// rev = [number, hash]
rev = utilities.generateNextRevision(prev_rev, ''+doc+' '+now+'');
doc._rev = rev.join('-');
doc._revisions.ids.unshift(rev[1]);
doc._revisions.start = rev[0];
doc._revs_info[0].status = 'deleted';
doc._revs_info.unshift({
"rev": rev.join('-'),
"status": "available"
});
localstorage.setItem(docpath, doc);
that.success (
priv.manageOptions(
{"ok":true,"id":docid,"rev":doc._rev},
command,
doc
)
);
});
}; // end putAttachment
......@@ -573,13 +578,14 @@ var newLocalStorage = function ( spec, my ) {
* the user.
* @method allDocs
*/
// ============== NOT MODIFIED YET ===============
that.allDocs = function (command) {
setTimeout(function () {
var new_array = [], array = [], i, l, k = 'key',
path = 'jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname, file_object = {};
path = 'jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname, file_object = {};
array = priv.getFileNameArray();
for (i = 0, l = array.length; i < l; i += 1) {
......@@ -614,7 +620,7 @@ var newLocalStorage = function ( spec, my ) {
// wait a little in order to simulate asynchronous saving
setTimeout (function () {
var docid, doc, docpath, prev_rev, attmtid, attmt, attpath;
docid = command.getDocId();
docid = command.getDocId(),
docpath = 'jio/local/'+priv.secured_username+'/'+
priv.secured_applicationname+'/'+docid;
prev_rev = command.getDocInfo('_rev');
......
......@@ -80,6 +80,8 @@ var command = function(spec, my) {
* @return {object} the document.
*/
that.getDoc = function() {
console.log("where is my doc");
console.log( priv.doc );
return priv.doc;
};
......
......@@ -359,10 +359,12 @@ test ('All tests', function () {
_creation_date:10000},'dummyallok loading');
o.jio.get('file',o.f);
o.tick(o);
// remove
o.spy(o,'value',{ok:true,id:"file"},'dummyallok removing');
o.jio.remove({_id:'file'},o.f);
o.tick(o);
// get list
o.spy (o,'value',{
total_rows:2,
......@@ -726,25 +728,37 @@ test ('Post', function(){
test ('Put', function(){
// runs following assertions
// 1) PUT without ID = 409
// 2) PUT with wrong ID/rev = 404
// 3) PUT CREATE
// 4) check file was created
// 5) check tree was created
// 6) PUT UPDATE
// 7) check file was replaced
// 8) check tree was updated
// 9) PUT UPDATE 2
// 10) check file was replaced
// 11) check tree was updated
// 12) PUT UPDATE false revision = 409
// 13) SYNC-PUT no revs_info = 409
// 14) SYNC-PUT revs_info
var o = {};
// 1) PUT without ID = 409
// 2) PUT with wrong ID/rev = 404
// 3) PUT CREATE response
// 4) check file was created
// 5) check tree was created
// 6) PUT UPDATE response
// 7) check file was replaced
// 8) check tree was updated
// 9) PUT UPDATE 2 response
// 10) check file was replaced
// 11) check tree was updated
// 12) PUT UPDATE false revision = 409
// 13) SYNC-PUT no revs_info = 409
// 14) SYNC-PUT revs_info response
// 15) check if file created
// 16) check if tree was merged
// 17) SYNC-PUT revs_info dead leaf response
// 18) check that file was NOT created
// 19) check that tree was updated
var fake_rev_0,
fake_rev_1,
fake_rev_2,
fake_id_0,
fake_id_1,
fake_id_2,
o = {};
o.t = this;
o.clock = o.t.sandbox.useFakeTimers(),
o.falseRevision,
o.clock = o.t.sandbox.useFakeTimers();
o.falseRevision;
localstorage = {
getItem: function (item) {
return JSON.parse (localStorage.getItem(item));
......@@ -791,6 +805,8 @@ test ('Put', function(){
"_rev":'1-ABCDEFG'},o.f);
checkReply(o,null,true);
o.clock.tick(base_tick);
// start adding content
o.jio.put({"content":'content',"_id":'myDoc'},
function(err, response) {
......@@ -813,9 +829,10 @@ test ('Put', function(){
});
// 3) TEST PUT content
// no idea why this is working for 3/6/9/12, but it does...
checkReply(o,null,true);
o.clock.tick(base_tick);
// update document
o.jio.put({"content":'content_modified',"_id":'myDoc',
"_rev":o.testRevisionStorage[0]},
......@@ -839,12 +856,13 @@ test ('Put', function(){
// 6) TEST PUT UPDATE
checkReply(o,null,true);
o.clock.tick(base_tick);
// update document 2nd time
o.jio.put({"content":'content_modified_again',
"_id":'myDoc',
"_rev":o.testRevisionStorage[0]},
function(err, response) {
var fake_rev_0,fake_rev_1,fake_id_0,fake_id_1;
o.spy(o,'value',{"ok":true,"id":response.id,
"rev":response.rev}, 'PUT content = ok');
......@@ -867,11 +885,9 @@ test ('Put', function(){
// 9) TEST PUT UPDATE
checkReply(o,null,true);
// continue to work with this instance
//o.jio.stop();
//o.clean;
o.clock.tick(base_tick);
// try updating with false revision
// TEST 12) PUT false revision
o.spy (o,'value',{
"error": 'conflict',
"message": 'Document update conflict.',
......@@ -884,11 +900,11 @@ test ('Put', function(){
o.jio.put({"content":'content_modified_false',
"_id":'myDoc',
"_rev":o.falseRevision},o.f);
// TEST 12) PUT false revision
checkReply(o,null,true);
o.clock.tick(base_tick);
// try updating without revs_info
// TEST 13) SYNC-PUT no revs_info
o.spy (o,'value',{
"error": 'conflict',
"message": 'Document update conflict.',
......@@ -901,9 +917,10 @@ test ('Put', function(){
o.jio.put({"content":'content_modified_false',
"_id":'myDoc',
"_rev":'1-abcdefg'},o.f);
// TEST 13) SYNC-PUT no revs_info
checkReply(o,null,true);
o.clock.tick(base_tick);
// add a new document version with fake revs_info
// the new document has the same origin and first edit,
// then it was changed to a new version (3-a9d...),
......@@ -912,10 +929,12 @@ test ('Put', function(){
// and add the two new dummy revisions into the final
// tree. Also the new document should be stored
// in local storage.
fake_rev_2 = o.testRevisionStorage[2];
fake_rev_1 = o.testRevisionStorage[1];
fake_rev_0 = o.testRevisionStorage[0];
fake_id_0 = o.testRevisionStorage[0].split('-')[1];
fake_id_2 = o.testRevisionStorage[2].split('-')[1];
fake_id_1 = o.testRevisionStorage[1].split('-')[1];
fake_id_0 = o.testRevisionStorage[0].split('-')[1];
// put a new document version
o.jio.put({
......@@ -927,7 +946,7 @@ test ('Put', function(){
{"rev":"3-a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123","status":"deleted"},
{"rev":fake_rev_1,"status":"deleted"},
{"rev":fake_rev_0,"status":"deleted"}
],
],
"_revisions":{
"start":4,
"ids":[
......@@ -970,7 +989,80 @@ test ('Put', function(){
// 14) TEST PUT UPDATE
checkReply(o,null,true);
o.clock.tick(base_tick);
/*
// put a new deleted version
o.jio.put({
"content":'a_deleted_version',
"_id":'myDoc',
"_rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61",
"_revs_info":[
{"rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61","status":"deleted"},
{"rev":"2-67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844","status":"deleted"},
{"rev":fake_rev_2,"status":"deleted"}
],
"_revisions":{
"start":3,
"ids":[
"05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61",
"67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844",
fake_id_2
]}
},
function(err, response) {
//o.testRevisionStorage.unshift(response.rev);
o.buildTestTree = {
"kids":[{
"kids":[
{"kids":[],
"rev":o.testRevisionStorage[0],
"status":'available',
"type":'leaf'
},
{"kids":[{
"kids":[],
"rev":"4-b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89",
"status":'available', "type":'leaf'
}],
"rev":"3-a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123",
"status":'deleted',
"type":'branch'
}],
"rev":o.testRevisionStorage[1],
"status":'deleted',
"type":'branch'
},{
"kids":[
{
"kids":[],
"rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61",
"status":'deleted',
"type":'leaf'
}],
"rev":"2-67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844",
"status":'deleted',
"typ":'branch'
}],
"rev":o.testRevisionStorage[2],
"status":'deleted',
"type":'branch'
};
o.spy(o,'value',{"ok":true,"id":response.id,
"rev":response.rev}, 'PUT SYNC dead leaf = ok');
o.f(response);
// TEST 18) check document was stored
//checkFile(response, o, null, true);
// TEST 19) check tree was updated
//checkTreeNode(response, o, null, true);
});
// 17) TEST PUT UPDATE
//checkReply(o,null,true);
*/
});
......
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