Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio_mebibou
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Alexandra Rogova
jio_mebibou
Commits
fdb950be
Commit
fdb950be
authored
Jan 07, 2013
by
Sven Franck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
revisionstorage get/remove
parent
0c109099
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
527 additions
and
38 deletions
+527
-38
src/jio.storage/revisionstorage.js
src/jio.storage/revisionstorage.js
+260
-22
test/jiotests.js
test/jiotests.js
+267
-16
No files found.
src/jio.storage/revisionstorage.js
View file @
fdb950be
...
...
@@ -117,13 +117,6 @@ jIO.addStorageType('revision', function (spec, my) {
return
{
"
rev
"
:
revision
,
"
status
"
:
status
,
"
children
"
:
children
||
[]};
};
/**
* Gets the winner revision from a document tree.
* The winner is the deeper revision on the left.
* @method getWinnerRevisionFromDocumentTree
* @param {object} document_tree The document tree
* @return {array} The winner revs info array
*/
/**
* Gets the winner revision from a document tree.
* The winner is the deeper revision on the left.
...
...
@@ -163,7 +156,11 @@ jIO.addStorageType('revision', function (spec, my) {
}
};
search
(
document_tree
,
0
);
return
result
;
// xxx shouldn't this return only a single revision
// from the document tree? Currently multiple revisions
// are passed back
// return result;
return
[
result
[
0
]];
};
/**
...
...
@@ -171,12 +168,19 @@ jIO.addStorageType('revision', function (spec, my) {
* @method postToDocumentTree
* @param {object} doctree The document tree object
* @param {object} doc The document object
* @param {boolean} set_node_to_deleted true/false
* @return {array} The added document revs_info
*/
priv
.
postToDocumentTree
=
function
(
doctree
,
doc
)
{
var
i
,
revs_info
,
next_rev
,
next_rev_str
,
selectNode
,
selected_node
;
revs_info
=
[];
selected_node
=
doctree
;
priv
.
postToDocumentTree
=
function
(
doctree
,
doc
,
set_node_to_deleted
)
{
var
i
,
revs_info
,
next_rev
,
next_rev_str
,
next_rev_status
,
selectNode
,
selected_node
,
revs_info
=
[],
selected_node
=
doctree
;
if
(
doc
.
_rev
===
undefined
&&
priv
.
missing_revision
){
doc
.
_rev
=
priv
.
missing_revision
;
}
selectNode
=
function
(
node
)
{
var
i
;
if
(
typeof
node
.
rev
!==
"
undefined
"
)
{
...
...
@@ -214,15 +218,17 @@ jIO.addStorageType('revision', function (spec, my) {
next_rev
=
priv
.
generateNextRevision
(
doc
.
_rev
||
0
,
JSON
.
stringify
(
doc
)
+
JSON
.
stringify
(
revs_info
));
next_rev_str
=
next_rev
.
join
(
"
-
"
);
next_rev_status
=
set_node_to_deleted
===
true
?
"
deleted
"
:
"
available
"
;
// don't add if the next rev already exists
for
(
i
=
0
;
i
<
selected_node
.
children
.
length
;
i
+=
1
)
{
if
(
selected_node
.
children
[
i
].
rev
===
next_rev_str
)
{
revs_info
.
unshift
({
"
rev
"
:
next_rev_str
,
"
status
"
:
"
available
"
"
status
"
:
next_rev_status
});
if
(
selected_node
.
children
[
i
].
status
!==
"
available
"
)
{
selected_node
.
children
[
i
].
status
=
"
available
"
;
if
(
selected_node
.
children
[
i
].
status
!==
next_rev_status
)
{
selected_node
.
children
[
i
].
status
=
next_rev_status
;
}
return
revs_info
;
}
...
...
@@ -270,6 +276,23 @@ jIO.addStorageType('revision', function (spec, my) {
return
result
;
};
/**
* Check if revision is a leaf
* @method isRevisionALeaf
* @param {string} revision revision to check
* @param {array} leaves all leaves on tree
* @return {boolean} true/false
*/
priv
.
isRevisionALeaf
=
function
(
revision
,
leaves
)
{
var
i
;
for
(
i
=
0
;
i
<
leaves
.
length
;
i
+=
1
)
{
if
(
leaves
[
i
]
===
revision
){
return
true
;
}
}
return
false
;
};
/**
* Convert revs_info to a simple revisions history
* @method revsInfoToHistory
...
...
@@ -299,6 +322,7 @@ jIO.addStorageType('revision', function (spec, my) {
var
f
=
{},
doctree
,
revs_info
,
doc
,
docid
;
doc
=
command
.
cloneDoc
();
docid
=
command
.
getDocId
();
if
(
typeof
doc
.
_rev
===
"
string
"
&&
!
priv
.
checkRevisionFormat
(
doc
.
_rev
))
{
that
.
error
({
...
...
@@ -329,6 +353,7 @@ jIO.addStorageType('revision', function (spec, my) {
docid
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
doctree
=
response
;
if
(
priv
.
update_doctree_allowed
)
{
f
.
postDocument
(
"
put
"
);
...
...
@@ -356,8 +381,12 @@ jIO.addStorageType('revision', function (spec, my) {
);
};
f
.
postDocument
=
function
(
doctree_update_method
)
{
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
doc
);
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
doc
,
priv
.
update_doctree_on_remove
);
// I don't understand why?
doc
.
_id
=
docid
+
"
.
"
+
revs_info
[
0
].
rev
;
that
.
addJob
(
"
post
"
,
priv
.
substorage
,
...
...
@@ -365,7 +394,8 @@ jIO.addStorageType('revision', function (spec, my) {
command
.
cloneOption
(),
function
(
response
)
{
f
.
sendDocumentTree
(
doctree_update_method
);
},
function
(
err
)
{
},
function
(
err
)
{
switch
(
err
.
status
)
{
case
409
:
// file already exists
...
...
@@ -387,12 +417,14 @@ jIO.addStorageType('revision', function (spec, my) {
doctree
,
command
.
cloneOption
(),
function
(
response
)
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
docid
,
"
rev
"
:
revs_info
[
0
].
rev
})
},
function
(
err
)
{
});
},
function
(
err
)
{
// xxx do we try to delete the posted document ?
err
.
message
=
"
Cannot save document revision tree
"
;
that
.
error
(
err
);
...
...
@@ -427,7 +459,7 @@ jIO.addStorageType('revision', function (spec, my) {
* @param {object} command The JIO command
*/
that
.
get
=
function
(
command
)
{
var
f
=
{},
doctree
,
revs_info
,
prev_rev
,
rev
s_info
,
option
;
var
f
=
{},
doctree
,
revs_info
,
prev_rev
,
rev
_path
,
option
;
option
=
command
.
cloneOption
();
if
(
option
[
"
max_retry
"
]
===
0
)
{
option
[
"
max_retry
"
]
=
3
;
...
...
@@ -479,7 +511,6 @@ jIO.addStorageType('revision', function (spec, my) {
docid
,
option
,
function
(
response
)
{
var
i
,
conflict_array
;
if
(
typeof
response
!==
"
string
"
)
{
response
.
_id
=
command
.
getDocId
();
response
.
_rev
=
prev_rev
;
...
...
@@ -506,11 +537,218 @@ jIO.addStorageType('revision', function (spec, my) {
);
};
if
(
command
.
getAttachmentId
())
{
f
.
getDocument
(
command
.
getDocId
()
+
"
/
"
+
command
.
getAttachmentId
());
// xxx: no revision passed = get tree and winning revision
if
(
prev_rev
===
undefined
){
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
command
.
getDocId
()
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
rev_path
=
"
.
"
+
priv
.
getWinnerRevisionFromDocumentTree
(
response
)[
0
].
rev
;
f
.
getDocument
(
command
.
getDocId
()
+
rev_path
+
"
/
"
+
command
.
getAttachmentId
());
},
function
(
err
)
{
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Document tree not found, please check document ID
"
,
"
reason
"
:
"
Incorrect document ID
"
});
return
;
}
);
}
else
{
f
.
getDocument
(
command
.
getDocId
()
+
"
.
"
+
prev_rev
+
"
/
"
+
command
.
getAttachmentId
());
}
}
else
{
f
.
getDocumentTree
();
}
};
/**
* Remove document or attachment.
* Options:
* - {boolean} keep_revision_history To keep the previous revisions
* @method remove
* @param {object} command The JIO command
*/
that
.
remove
=
function
(
command
)
{
var
f
=
{},
del_rev
,
option
,
i
,
revision_found
=
false
,
revision_count
=
0
,
correct_revision
;
option
=
command
.
cloneOption
();
if
(
option
[
"
max_retry
"
]
===
0
)
{
option
[
"
max_retry
"
]
=
3
;
}
del_rev
=
command
.
getDoc
().
_rev
;
f
.
removeDocument
=
function
(
docid
)
{
if
(
command
.
getOption
(
"
keep_revision_history
"
)
!==
true
)
{
that
.
addJob
(
"
remove
"
,
priv
.
substorage
,
docid
,
option
,
function
(
response
)
{
if
(
command
.
getAttachmentId
()
===
undefined
)
{
priv
.
update_doctree_on_remove
=
true
;
}
else
{
priv
.
update_doctree_on_remove
=
false
;
}
that
.
post
(
command
);
},
function
(
err
)
{
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
File not found
"
,
"
reason
"
:
"
Document was not found
"
});
return
;
}
);
}
else
{
// keep history = update document tree only
if
(
command
.
getAttachmentId
()
===
undefined
)
{
priv
.
update_doctree_on_remove
=
true
;
}
else
{
priv
.
update_doctree_on_remove
=
false
;
}
that
.
post
(
command
);
}
};
if
(
typeof
del_rev
===
"
string
"
)
{
if
(
!
priv
.
checkRevisionFormat
(
del_rev
))
{
that
.
error
({
"
status
"
:
31
,
"
statusText
"
:
"
Wrong Revision Format
"
,
"
error
"
:
"
wrong_revision_format
"
,
"
message
"
:
"
The document previous revision does not match
"
+
"
[0-9]+-[0-9a-zA-Z]+
"
,
"
reason
"
:
"
Previous revision is wrong
"
});
return
;
}
}
// get doctree
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
command
.
getDocId
()
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
response
.
_conflicts
=
priv
.
getLeavesFromDocumentTree
(
response
);
// really necessary...?
if
(
del_rev
===
undefined
)
{
// single leaf = can be deleted
if
(
response
.
_conflicts
.
length
===
1
)
{
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
response
.
_conflicts
[
0
]);
delete
response
.
_conflicts
;
}
else
{
// multiple leaves = only if deleting attachment,
// because unique document.revision/attachment
if
(
typeof
command
.
getAttachmentId
()
===
"
string
"
){
for
(
i
=
0
;
i
<
response
.
_conflicts
.
length
;
i
+=
1
){
del_rev
=
response
.
_conflicts
[
i
];
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
command
.
getDocId
()
+
"
.
"
+
response
.
_conflicts
[
i
],
option
,
function
(
nested_response
)
{
if
(
typeof
nested_response
.
_attachments
===
"
object
"
)
{
if
(
nested_response
.
_attachments
[
command
.
getAttachmentId
()]
!==
undefined
){
revision_found
=
true
;
correct_revision
=
del_rev
;
}
}
if
(
revision_count
===
response
.
_conflicts
.
length
-
1
&&
revision_found
!==
true
){
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Attachment not found, please check attachment ID
"
,
"
reason
"
:
"
Incorrect Attachment ID
"
});
return
;
}
if
(
revision_found
===
true
){
priv
.
missing_revision
=
correct_revision
;
delete
response
.
_conflicts
;
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
correct_revision
+
"
/
"
+
command
.
getAttachmentId
());
}
revision_count
+=
1
;
},
function
(
err
)
{
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Attachment not found, please check document ID
"
,
"
reason
"
:
"
Incorrect document ID
"
});
}
);
}
}
else
{
// conflict
// return conflict message here, so user can pick a document version
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Cannot delete a document without revision when multiple versions exist
"
});
return
;
}
}
}
else
{
// revision provided
if
(
typeof
command
.
getAttachmentId
()
===
"
string
"
){
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
del_rev
+
"
/
"
+
command
.
getAttachmentId
());
}
else
{
if
(
priv
.
isRevisionALeaf
(
del_rev
,
response
.
_conflicts
)){
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
del_rev
);
}
else
{
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Trying to remove an outdated revision
"
});
return
;
}
}
}
},
function
(
err
)
{
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Document tree not found, please check document ID
"
,
"
reason
"
:
"
Incorrect document ID
"
});
return
;
}
);
};
return
that
;
});
test/jiotests.js
View file @
fdb950be
...
...
@@ -1228,11 +1228,11 @@ test ("Get", function(){
// adding two documents
o
.
doctree
=
{
"
children
"
:[{
"
rev
"
:
"
1-rev1
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
},{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
"
1-rev1
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
"
2-rev3
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
}]
},{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
}]};
o
.
doc_myget2
=
{
"
_id
"
:
"
get1
"
,
"
title
"
:
"
myGet2
"
};
o
.
doc_myget3
=
{
"
_id
"
:
"
get1
"
,
"
title
"
:
"
myGet3
"
};
...
...
@@ -1260,16 +1260,8 @@ test ("Get", function(){
o
.
tick
(
o
);
delete
o
.
doc_myget2
[
"
_rev
"
];
// adding an attachment
o
.
attmt_myget2
=
{
"
get2
"
:
{
"
length
"
:
3
,
"
digest
"
:
"
md5-dontcare
"
}
};
o
.
doctree
[
"
children
"
][
1
][
"
attachment
"
]
=
o
.
attmt_myget2
;
localstorage
.
setItem
(
o
.
localpath
+
"
/get1.1-rev2
"
,
o
.
doc_myget2
);
localstorage
.
setItem
(
o
.
localpath
+
"
/get1.1-rev2/get2
"
,
"
abc
"
);
// localstorage.setItem(o.localpath+"/get1.1-rev2/get2", "abc");
localstorage
.
setItem
(
o
.
localpath
+
"
/get1.2-rev3/get2
"
,
"
abc
"
);
// get attachment winner
o
.
spy
(
o
,
"
value
"
,
"
abc
"
,
"
Get attachment (winner)
"
);
...
...
@@ -1283,13 +1275,24 @@ test ("Get", function(){
// get attachment specific rev
o
.
spy
(
o
,
"
value
"
,
"
abc
"
,
"
Get attachment (specific revision)
"
);
o
.
jio
.
get
(
"
get1/get2
"
,
{
"
rev
"
:
"
1-rev2
"
},
o
.
f
);
o
.
jio
.
get
(
"
get1/get2
"
,
{
"
rev
"
:
"
2-rev3
"
},
o
.
f
);
o
.
tick
(
o
);
// get document with attachment (specific revision)
o
.
attmt_myget2
[
"
get2
"
][
"
revpos
"
]
=
1
;
// adding an attachment
o
.
attmt_myget2
=
{
"
get2
"
:
{
"
length
"
:
3
,
"
digest
"
:
"
md5-dontcare
"
},
"
revpos
"
:
1
,
};
o
.
doc_myget2
[
"
_rev
"
]
=
"
1-rev2
"
;
o
.
doc_myget2
[
"
_attachments
"
]
=
o
.
attmt_myget2
;
o
.
doctree
[
"
children
"
][
1
][
"
attachment
"
]
=
o
.
attmt_myget2
;
localstorage
.
setItem
(
o
.
localpath
+
"
/get1.1-rev2
"
,
o
.
doc_myget2
);
// get document with attachment (specific revision)
o
.
spy
(
o
,
"
value
"
,
o
.
doc_myget2
,
"
Get document attachment (specific revision)
"
);
o
.
jio
.
get
(
"
get1
"
,
{
"
rev
"
:
"
1-rev2
"
},
o
.
f
);
...
...
@@ -1300,6 +1303,10 @@ test ("Get", function(){
// get document with attachment (winner)
o
.
doc_myget3
[
"
_rev
"
]
=
"
2-rev3
"
;
o
.
doc_myget3
[
"
_attachments
"
]
=
o
.
attmt_myget2
;
o
.
doctree
[
"
children
"
][
1
][
"
attachment
"
]
=
o
.
attmt_myget3
;
localstorage
.
setItem
(
o
.
localpath
+
"
/get1.2-rev3
"
,
o
.
doc_myget3
);
o
.
spy
(
o
,
"
value
"
,
o
.
doc_myget3
,
"
Get document attachment (winner)
"
);
o
.
jio
.
get
(
"
get1
"
,
o
.
f
);
o
.
tick
(
o
);
...
...
@@ -1311,6 +1318,250 @@ test ("Get", function(){
});
test
(
"
Remove
"
,
function
(){
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
revision
"
,
"
secondstorage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
urevrem
"
,
"
applicationname
"
:
"
arevrem
"
}
});
o
.
localpath
=
"
jio/localstorage/urevrem/arevrem
"
;
// adding two documents
o
.
doc_myremove1
=
{
"
_id
"
:
"
remove1
"
,
"
title
"
:
"
myRemove1
"
};
o
.
doc_myremove2
=
{
"
_id
"
:
"
remove1
"
,
"
title
"
:
"
myRemove2
"
};
// revs_info 1-rev1 document version
o
.
revs_info
=
[];
o
.
very_old_rev
=
"
1-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_myremove1
)
+
JSON
.
stringify
(
o
.
revs_info
));
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.
"
+
o
.
very_old_rev
,
o
.
doc_myremove1
);
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.1-rev2
"
,
o
.
doc_myremove1
);
// add attachment
o
.
attmt_myremove1
=
{
"
remove2
"
:
{
"
length
"
:
3
,
"
digest
"
:
"
md5-dontcare
"
},
"
revpos
"
:
1
};
o
.
doc_myremove1
=
{
"
_id
"
:
"
remove1
"
,
"
title
"
:
"
myRemove1
"
,
"
_rev
"
:
o
.
very_old_rev
,
"
_attachments
"
:
o
.
attmt_myremove1
};
o
.
revs_info
=
[{
"
rev
"
:
o
.
very_old_rev
,
"
status
"
:
"
available
"
}];
o
.
old_rev
=
"
2-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_myremove1
)
+
JSON
.
stringify
(
o
.
revs_info
));
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.
"
+
o
.
old_rev
,
o
.
doc_myremove1
);
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.
"
+
o
.
old_rev
+
"
/remove2
"
,
"
xyz
"
);
o
.
doctree
=
{
"
children
"
:[{
"
rev
"
:
o
.
very_old_rev
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
o
.
old_rev
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
}]
},{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
}]};
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.revision_tree.json
"
,
o
.
doctree
);
// 1. remove non existing attachment with revision
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove non existing attachment (with revision)
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1.1-rev2/remove0
"
,
"
_rev
"
:
o
.
old_rev
},
o
.
f
);
o
.
tick
(
o
);
o
.
revs_info
=
[
{
"
rev
"
:
o
.
old_rev
,
"
status
"
:
"
available
"
},
{
"
rev
"
:
o
.
very_old_rev
,
"
status
"
:
"
available
"
}
];
// xxx on remove, doc only includes the parameters passed in the remove callback
// to generate correct hash, need to modify here
o
.
doc_myremove1
=
{
"
_id
"
:
"
remove1/remove2
"
,
"
_rev
"
:
o
.
old_rev
};
o
.
rev
=
"
3-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_myremove1
)
+
JSON
.
stringify
(
o
.
revs_info
));
o
.
doctree
=
{
"
children
"
:[{
"
rev
"
:
o
.
very_old_rev
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
o
.
old_rev
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
o
.
rev
,
"
status
"
:
"
available
"
,
"
children
"
:[]
}]
}]
},{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[]
}]};
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.revision_tree.json
"
,
o
.
doctree
);
// 2. remove existing attachment with revision
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
remove1
"
,
"
rev
"
:
o
.
rev
},
"
Remove attachment (with revision)
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1/remove2
"
,
"
_rev
"
:
o
.
old_rev
},
o
.
f
);
o
.
tick
(
o
);
// add another attachment
o
.
attmt_myremove2
=
{
"
remove3
"
:
{
"
length
"
:
3
,
"
digest
"
:
"
md5-hello123
"
},
"
revpos
"
:
1
};
o
.
doc_myremove2
=
{
"
_id
"
:
"
remove1
"
,
"
title
"
:
"
myRemove2
"
,
"
_rev
"
:
"
1-rev2
"
,
"
_attachments
"
:
o
.
attmt_myremove2
};
o
.
second_old_rev
=
"
2-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_myremove1
)
+
JSON
.
stringify
(
o
.
revs_info
));
o
.
revs_info
=
[
{
"
rev
"
:
o
.
second_old_rev
,
"
status
"
:
"
available
"
},
{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
}
];
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.
"
+
o
.
second_old_rev
,
o
.
doc_myremove2
);
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.
"
+
o
.
second_old_rev
+
"
/remove3
"
,
"
stu
"
);
o
.
doctree
=
{
"
children
"
:[{
"
rev
"
:
o
.
very_old_rev
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
o
.
old_rev
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
o
.
rev
,
"
status
"
:
"
available
"
,
"
children
"
:[]
}]
}]
},{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
,
"
children
"
:
[{
"
rev
"
:
o
.
second_old_rev
,
"
status
"
:
"
available
"
,
"
children
"
:[]
}]
}]};
localstorage
.
setItem
(
o
.
localpath
+
"
/remove1.revision_tree.json
"
,
o
.
doctree
);
// 3. remove non existing attachment without revision
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove non existing attachment (without revision)
"
)
o
.
jio
.
remove
({
"
_id
"
:
"
remove1/remove0
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
revs_info
=
[
{
"
rev
"
:
o
.
second_old_rev
,
"
status
"
:
"
available
"
},
{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
}
];
o
.
doc_myremove3
=
{
"
_id
"
:
"
remove1/remove3
"
,
"
_rev
"
:
o
.
second_old_rev
};
o
.
second_rev
=
"
3-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_myremove3
)
+
JSON
.
stringify
(
o
.
revs_info
));
// 4. remove existing attachment without revision
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
remove1
"
,
"
rev
"
:
o
.
second_rev
},
"
Remove attachment (without revision)
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1/remove3
"
},
o
.
f
);
o
.
tick
(
o
);
// 5. remove wrong revision
o
.
spy
(
o
,
"
status
"
,
409
,
"
Removing wrong revision (not latest)
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1
"
,
"
_rev
"
:
o
.
second_old_rev
},
o
.
f
);
o
.
tick
(
o
);
o
.
revs_info
=
[
{
"
rev
"
:
o
.
second_rev
,
"
status
"
:
"
available
"
},
{
"
rev
"
:
o
.
second_old_rev
,
"
status
"
:
"
available
"
},
{
"
rev
"
:
"
1-rev2
"
,
"
status
"
:
"
available
"
}
];
o
.
doc_myremove4
=
{
"
_id
"
:
"
remove1
"
,
"
_rev
"
:
o
.
second_rev
};
o
.
second_new_rev
=
"
4-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_myremove4
)
+
JSON
.
stringify
(
o
.
revs_info
));
// 6. remove revision
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
remove1
"
,
"
rev
"
:
o
.
second_new_rev
},
"
Remove attachment (with revision)
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1
"
,
"
_rev
"
:
o
.
second_rev
},
o
.
f
);
o
.
tick
(
o
);
// 7. remove document without revision
o
.
spy
(
o
,
"
status
"
,
409
,
"
Removing document without revision and multiple existing versions
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
module
(
"
Test Revisionstorage + Localstorage
"
);
test
(
"
sample
"
,
function
(){
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
revision
"
,
"
secondstorage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
usam1
"
,
"
applicationname
"
:
"
asam1
"
}
});
o
.
localpath
=
"
jio/localstorage/usam1/asam1
"
;
// 1. put non empty document A-1
o
.
doc
=
{
"
_id
"
:
"
sample1
"
,
"
title
"
:
"
mySample1
"
};
o
.
revs_info
=
[];
o
.
rev
=
"
1-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc
)
+
JSON
.
stringify
(
o
.
revs_info
));
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
sample1
"
,
"
rev
"
:
o
.
rev
},
"
Put non empty document A-1
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// 2. put non empty document A-2
o
.
doc_b
=
{
"
_id
"
:
"
sample1
"
,
"
title
"
:
"
mySample2
"
};
o
.
revs_info_b
=
[];
o
.
rev_b
=
"
1-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc
)
+
JSON
.
stringify
(
o
.
revs_info
));
o
.
spy
(
o
,
"
status
"
,
409
,
"
409 Try to put non empty document A-2
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// 3. FAKE IT
o
.
doc_f
=
{
"
_id
"
:
"
sample1
"
,
"
title
"
:
"
mySample2
"
};
o
.
revs_info_f
=
[];
o
.
rev_f
=
"
1-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_f
)
+
JSON
.
stringify
(
o
.
revs_info_f
));
o
.
doc_f2
=
{
"
_id
"
:
"
sample1.
"
+
o
.
rev_f
,
"
title
"
:
"
mySample2
"
};
localstorage
.
setItem
(
o
.
localpath
+
"
/sample1.
"
+
o
.
rev_f
,
o
.
doc_f2
);
o
.
doctree
=
{
"
children
"
:[
{
"
rev
"
:
o
.
rev
,
"
status
"
:
"
available
"
,
"
children
"
:
[]},
{
"
rev
"
:
o
.
rev_f
,
"
status
"
:
"
available
"
,
"
children
"
:
[]}
]};
localstorage
.
setItem
(
o
.
localpath
+
"
/sample1.revision_tree.json
"
,
o
.
doctree
);
// 3. GET first version
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
sample1
"
,
"
title
"
:
"
mySample1
"
,
"
_rev
"
:
o
.
rev
},
"
Get first document (using revison)
"
);
o
.
jio
.
get
(
"
sample1
"
,
{
"
rev
"
:
o
.
rev
},
o
.
f
);
o
.
tick
(
o
);
// 4. MODFIY first version
o
.
doc_2
=
{
"
_id
"
:
"
sample1
"
,
"
_rev
"
:
o
.
rev
,
"
title
"
:
"
mySample1_modified
"
};
o
.
revs_info_2
=
[{
"
rev
"
:
o
.
rev
,
"
status
"
:
"
available
"
}];
o
.
rev_2
=
"
2-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_2
)
+
JSON
.
stringify
(
o
.
revs_info_2
));
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
sample1
"
,
"
ok
"
:
true
,
"
rev
"
:
o
.
rev_2
},
"
Modify first document
"
);
o
.
jio
.
put
(
o
.
doc_2
,
o
.
f
);
o
.
tick
(
o
);
// 5. GET second version
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
sample1
"
,
"
title
"
:
"
mySample2
"
,
"
_rev
"
:
o
.
rev_f
},
"
Get second document (using revison)
"
);
o
.
jio
.
get
(
"
sample1
"
,
{
"
rev
"
:
o
.
rev_f
},
o
.
f
);
o
.
tick
(
o
);
// 6. MODFIY second version
o
.
doc_f2
=
{
"
_id
"
:
"
sample1
"
,
"
_rev
"
:
o
.
rev_f
,
"
title
"
:
"
mySample2_modified
"
};
o
.
revs_info_f2
=
[{
"
rev
"
:
o
.
rev_f
,
"
status
"
:
"
available
"
}];
o
.
rev_f2
=
"
2-
"
+
hex_sha256
(
JSON
.
stringify
(
o
.
doc_f2
)
+
JSON
.
stringify
(
o
.
revs_info_f2
));
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
sample1
"
,
"
ok
"
:
true
,
"
rev
"
:
o
.
rev_f2
},
"
Modify second document
"
);
o
.
jio
.
put
(
o
.
doc_f2
,
o
.
f
);
o
.
tick
(
o
);
// 7. GET document with conflict!
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
sample1
"
,
"
title
"
:
"
mySample2
"
,
"
_rev
"
:
o
.
rev_f
},
"
Get second document (using revison)
"
);
o
.
jio
.
get
(
"
sample1
"
,
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
/*
module ('Jio DAVStorage');
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment