Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Xiaowu Zhang
jio
Commits
bc17b228
Commit
bc17b228
authored
Jan 10, 2013
by
Sven Franck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jslint pass revisionstorage.js
parent
e45edf9f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
834 additions
and
826 deletions
+834
-826
src/jio.storage/revisionstorage.js
src/jio.storage/revisionstorage.js
+834
-826
No files found.
src/jio.storage/revisionstorage.js
View file @
bc17b228
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global jIO: true, hex_sha256: true, setTimeout: true */
/**
/**
* JIO Revision Storage.
* JIO Revision Storage.
* It manages document version and can generate conflicts.
* It manages document version and can generate conflicts.
...
@@ -8,869 +10,875 @@
...
@@ -8,869 +10,875 @@
* }
* }
*/
*/
jIO
.
addStorageType
(
'
revision
'
,
function
(
spec
,
my
)
{
jIO
.
addStorageType
(
'
revision
'
,
function
(
spec
,
my
)
{
"
use strict
"
;
"
use strict
"
;
var
that
,
priv
=
{};
var
that
,
priv
=
{};
spec
=
spec
||
{};
spec
=
spec
||
{};
that
=
my
.
basicStorage
(
spec
,
my
);
that
=
my
.
basicStorage
(
spec
,
my
);
priv
.
substorage_key
=
"
sub_storage
"
;
priv
.
substorage_key
=
"
sub_storage
"
;
priv
.
doctree_suffix
=
"
.revision_tree.json
"
;
priv
.
doctree_suffix
=
"
.revision_tree.json
"
;
priv
.
substorage
=
spec
[
priv
.
substorage_key
];
priv
.
substorage
=
spec
[
priv
.
substorage_key
];
that
.
specToStore
=
function
()
{
that
.
specToStore
=
function
()
{
var
o
=
{};
var
o
=
{};
o
[
priv
.
substorage_key
]
=
priv
.
substorage
;
o
[
priv
.
substorage_key
]
=
priv
.
substorage
;
return
o
;
return
o
;
};
/**
* Generate a new uuid
* @method generateUuid
* @return {string} The new uuid
*/
priv
.
generateUuid
=
function
()
{
var
S4
=
function
()
{
/* 65536 */
var
i
,
string
=
Math
.
floor
(
Math
.
random
()
*
0x10000
).
toString
(
16
);
for
(
i
=
string
.
length
;
i
<
4
;
i
+=
1
)
{
string
=
'
0
'
+
string
;
}
return
string
;
};
};
return
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
/**
S4
()
+
S4
();
* Generate a new uuid
};
* @method generateUuid
* @return {string} The new uuid
/**
*/
* Generates a hash code of a string
priv
.
generateUuid
=
function
()
{
* @method hashCode
var
S4
=
function
()
{
* @param {string} string The string to hash
var
i
,
string
=
Math
.
floor
(
* @return {string} The string hash code
Math
.
random
()
*
0x10000
/* 65536 */
*/
).
toString
(
16
);
priv
.
hashCode
=
function
(
string
)
{
for
(
i
=
string
.
length
;
i
<
4
;
i
+=
1
)
{
return
hex_sha256
(
string
);
string
=
'
0
'
+
string
;
};
}
return
string
;
/**
};
* Returns an array version of a revision string
return
S4
()
+
S4
()
+
"
-
"
+
* @method revisionToArray
S4
()
+
"
-
"
+
* @param {string} revision The revision string
S4
()
+
"
-
"
+
* @return {array} Array containing a revision number and a hash
S4
()
+
"
-
"
+
*/
S4
()
+
S4
()
+
S4
();
priv
.
revisionToArray
=
function
(
revision
)
{
if
(
typeof
revision
===
"
string
"
)
{
return
[
parseInt
(
revision
.
split
(
'
-
'
)[
0
],
10
),
revision
.
split
(
'
-
'
)[
1
]];
}
return
revision
;
};
/**
* Generates the next revision of [previous_revision]. [string] helps us
* to generate a hash code.
* @methode generateNextRev
* @param {string} previous_revision The previous revision
* @param {object} doc The document metadata
* @param {object} revisions The revision history
* @param {boolean} deleted_flag The deleted flag
* @return {array} 0:The next revision number and 1:the hash code
*/
priv
.
generateNextRevision
=
function
(
previous_revision
,
doc
,
revisions
,
deleted_flag
)
{
var
string
=
JSON
.
stringify
(
doc
)
+
JSON
.
stringify
(
revisions
)
+
JSON
.
stringify
(
deleted_flag
?
true
:
false
);
if
(
typeof
previous_revision
===
"
number
"
)
{
return
[
previous_revision
+
1
,
priv
.
hashCode
(
string
)];
}
previous_revision
=
priv
.
revisionToArray
(
previous_revision
);
return
[
previous_revision
[
0
]
+
1
,
priv
.
hashCode
(
string
)];
};
/**
* Checks a revision format
* @method checkRevisionFormat
* @param {string} revision The revision string
* @return {boolean} True if ok, else false
*/
priv
.
checkRevisionFormat
=
function
(
revision
)
{
return
(
/^
[
0-9
]
+-
[
0-9a-zA-Z
]
+$/
.
test
(
revision
));
};
/**
* Creates an empty document tree
* @method createDocumentTree
* @param {array} children An array of children (optional)
* @return {object} The new document tree
*/
priv
.
createDocumentTree
=
function
(
children
)
{
return
{
"
children
"
:
children
||
[]
};
};
};
/**
* Generates a hash code of a string
/**
* @method hashCode
* Creates a new document tree node
* @param {string} string The string to hash
* @method createDocumentTreeNode
* @return {string} The string hash code
* @param {string} revision The node revision
*/
* @param {string} status The node status
priv
.
hashCode
=
function
(
string
)
{
* @param {array} children An array of children (optional)
return
hex_sha256
(
string
);
* @return {object} The new document tree node
*/
priv
.
createDocumentTreeNode
=
function
(
revision
,
status
,
children
)
{
return
{
"
rev
"
:
revision
,
"
status
"
:
status
,
"
children
"
:
children
||
[]
};
};
};
/**
* Returns an array version of a revision string
/**
* @method revisionToArray
* Gets the specific revision from a document tree.
* @param {string} revision The revision string
* @method getRevisionFromDocumentTree
* @return {array} Array containing a revision number and a hash
* @param {object} document_tree The document tree
*/
* @param {string} revision The specific revision
priv
.
revisionToArray
=
function
(
revision
)
{
* @return {array} The good revs info array
if
(
typeof
revision
===
"
string
"
)
{
*/
return
[
parseInt
(
revision
.
split
(
'
-
'
)[
0
],
10
),
priv
.
getRevisionFromDocumentTree
=
function
(
document_tree
,
revision
)
{
revision
.
split
(
'
-
'
)[
1
]]
var
result
,
search
,
revs_info
=
[];
result
=
[];
// search method fills "result" with the good revs info
search
=
function
(
document_tree
)
{
var
i
;
if
(
document_tree
.
rev
!==
undefined
)
{
// node is not root
revs_info
.
unshift
({
"
rev
"
:
document_tree
.
rev
,
"
status
"
:
document_tree
.
status
});
if
(
document_tree
.
rev
===
revision
)
{
result
=
revs_info
;
return
;
}
}
return
revision
;
}
};
// This node has children
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
/**
// searching deeper to find the good rev
* Generates the next revision of [previous_revision]. [string] helps us
search
(
document_tree
.
children
[
i
]);
* to generate a hash code.
if
(
result
.
length
>
0
)
{
* @methode generateNextRev
// The result is already found
* @param {string} previous_revision The previous revision
return
;
* @param {object} doc The document metadata
* @param {object} revisions The revision history
* @param {boolean} deleted_flag The deleted flag
* @return {array} 0:The next revision number and 1:the hash code
*/
priv
.
generateNextRevision
=
function
(
previous_revision
,
doc
,
revisions
,
deleted_flag
)
{
var
string
=
JSON
.
stringify
(
doc
)
+
JSON
.
stringify
(
revisions
)
+
JSON
.
stringify
(
deleted_flag
?
true
:
false
);
if
(
typeof
previous_revision
===
"
number
"
)
{
return
[
previous_revision
+
1
,
priv
.
hashCode
(
string
)];
}
}
previous_revision
=
priv
.
revisionToArray
(
previous_revision
);
revs_info
.
shift
();
return
[
previous_revision
[
0
]
+
1
,
priv
.
hashCode
(
string
)];
}
};
/**
* Checks a revision format
* @method checkRevisionFormat
* @param {string} revision The revision string
* @return {boolean} True if ok, else false
*/
priv
.
checkRevisionFormat
=
function
(
revision
)
{
return
(
/^
[
0-9
]
+-
[
0-9a-zA-Z
]
+$/
.
test
(
revision
));
};
/**
* Creates an empty document tree
* @method createDocumentTree
* @param {array} children An array of children (optional)
* @return {object} The new document tree
*/
priv
.
createDocumentTree
=
function
(
children
)
{
return
{
"
children
"
:
children
||
[]};
};
};
search
(
document_tree
);
/**
return
result
;
* Creates a new document tree node
};
* @method createDocumentTreeNode
* @param {string} revision The node revision
/**
* @param {string} status The node status
* Gets the winner revision from a document tree.
* @param {array} children An array of children (optional)
* The winner is the deeper revision on the left.
* @return {object} The new document tree node
* @method getWinnerRevisionFromDocumentTree
*/
* @param {object} document_tree The document tree
priv
.
createDocumentTreeNode
=
function
(
revision
,
status
,
children
)
{
* @return {array} The winner revs info array
return
{
"
rev
"
:
revision
,
"
status
"
:
status
,
"
children
"
:
children
||
[]};
*/
};
priv
.
getWinnerRevisionFromDocumentTree
=
function
(
document_tree
)
{
var
result
,
search
,
revs_info
=
[];
/**
result
=
[];
* Gets the specific revision from a document tree.
// search method fills "result" with the winner revs info
* @method getRevisionFromDocumentTree
search
=
function
(
document_tree
,
deep
)
{
* @param {object} document_tree The document tree
var
i
;
* @param {string} revision The specific revision
if
(
document_tree
.
rev
!==
undefined
)
{
* @return {array} The good revs info array
// node is not root
*/
revs_info
.
unshift
({
priv
.
getRevisionFromDocumentTree
=
function
(
document_tree
,
revision
)
{
"
rev
"
:
document_tree
.
rev
,
var
i
,
result
,
search
,
revs_info
=
[];
"
status
"
:
document_tree
.
status
result
=
[];
});
// search method fills "result" with the good revs info
}
search
=
function
(
document_tree
)
{
if
(
document_tree
.
children
.
length
===
0
&&
document_tree
.
status
!==
var
i
;
"
deleted
"
)
{
if
(
typeof
document_tree
.
rev
!==
"
undefined
"
)
{
// This node is a leaf
// node is not root
if
(
result
.
length
<
deep
)
{
revs_info
.
unshift
({
// The leaf is deeper than result
"
rev
"
:
document_tree
.
rev
,
result
=
[];
"
status
"
:
document_tree
.
status
for
(
i
=
0
;
i
<
revs_info
.
length
;
i
+=
1
)
{
});
result
.
push
(
revs_info
[
i
]);
if
(
document_tree
.
rev
===
revision
)
{
}
result
=
revs_info
;
return
;
}
}
// This node has children
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
// searching deeper to find the good rev
search
(
document_tree
.
children
[
i
]);
if
(
result
.
length
>
0
)
{
// The result is already found
return
;
}
revs_info
.
shift
();
}
};
search
(
document_tree
);
return
result
;
};
/**
* 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
*/
priv
.
getWinnerRevisionFromDocumentTree
=
function
(
document_tree
)
{
var
i
,
result
,
search
,
revs_info
=
[];
result
=
[];
// search method fills "result" with the winner revs info
search
=
function
(
document_tree
,
deep
)
{
var
i
;
if
(
typeof
document_tree
.
rev
!==
"
undefined
"
)
{
// node is not root
revs_info
.
unshift
({
"
rev
"
:
document_tree
.
rev
,
"
status
"
:
document_tree
.
status
});
}
if
(
document_tree
.
children
.
length
===
0
&&
document_tree
.
status
!==
"
deleted
"
)
{
// This node is a leaf
if
(
result
.
length
<
deep
)
{
// The leaf is deeper than result
result
=
[];
for
(
i
=
0
;
i
<
revs_info
.
length
;
i
+=
1
)
{
result
.
push
(
revs_info
[
i
]);
}
}
return
;
}
// This node has children
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
// searching deeper to find the deeper leaf
search
(
document_tree
.
children
[
i
],
deep
+
1
);
revs_info
.
shift
();
}
};
search
(
document_tree
,
0
);
return
result
;
};
/**
* Add a document revision to the document tree
* @method postToDocumentTree
* @param {object} doctree The document tree object
* @param {object} doc The document object
* @param {boolean} set_node_to_deleted Set the revision to deleted
* @return {array} The added document revs_info
*/
priv
.
postToDocumentTree
=
function
(
doctree
,
doc
,
set_node_to_deleted
)
{
var
i
,
revs_info
,
next_rev
,
next_rev_str
,
selectNode
,
selected_node
,
flag
;
flag
=
set_node_to_deleted
===
true
?
"
deleted
"
:
"
available
"
;
revs_info
=
[];
selected_node
=
doctree
;
selectNode
=
function
(
node
)
{
var
i
;
if
(
typeof
node
.
rev
!==
"
undefined
"
)
{
// node is not root
revs_info
.
unshift
({
"
rev
"
:
node
.
rev
,
"
status
"
:
node
.
status
});
}
if
(
node
.
rev
===
doc
.
_rev
)
{
selected_node
=
node
;
return
"
node_selected
"
;
}
else
{
for
(
i
=
0
;
i
<
node
.
children
.
length
;
i
+=
1
)
{
if
(
selectNode
(
node
.
children
[
i
])
===
"
node_selected
"
)
{
return
"
node_selected
"
;
}
revs_info
.
shift
();
}
}
};
if
(
typeof
doc
.
_rev
===
"
string
"
)
{
// document has a previous revision
if
(
selectNode
(
selected_node
)
!==
"
node_selected
"
)
{
// no node was selected, so add a node with a specific rev
revs_info
.
unshift
({
"
rev
"
:
doc
.
_rev
,
"
status
"
:
"
missing
"
});
selected_node
.
children
.
unshift
({
"
rev
"
:
doc
.
_rev
,
"
status
"
:
"
missing
"
,
"
children
"
:
[]
});
selected_node
=
selected_node
.
children
[
0
];
}
}
}
next_rev
=
priv
.
generateNextRevision
(
return
;
doc
.
_rev
||
0
,
doc
,
priv
.
revsInfoToHistory
(
revs_info
),
}
set_node_to_deleted
);
// This node has children
next_rev_str
=
next_rev
.
join
(
"
-
"
);
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
// don't add if the next rev already exists
// searching deeper to find the deeper leaf
for
(
i
=
0
;
i
<
selected_node
.
children
.
length
;
i
+=
1
)
{
search
(
document_tree
.
children
[
i
],
deep
+
1
);
if
(
selected_node
.
children
[
i
].
rev
===
next_rev_str
)
{
revs_info
.
shift
();
revs_info
.
unshift
({
}
"
rev
"
:
next_rev_str
,
};
"
status
"
:
flag
search
(
document_tree
,
0
);
});
return
result
;
if
(
selected_node
.
children
[
i
].
status
!==
flag
)
{
};
selected_node
.
children
[
i
].
status
=
flag
;
}
/**
return
revs_info
;
* Add a document revision to the document tree
}
* @method postToDocumentTree
* @param {object} doctree The document tree object
* @param {object} doc The document object
* @param {boolean} set_node_to_deleted Set the revision to deleted
* @return {array} The added document revs_info
*/
priv
.
postToDocumentTree
=
function
(
doctree
,
doc
,
set_node_to_deleted
)
{
var
i
,
revs_info
,
next_rev
,
next_rev_str
,
selectNode
,
selected_node
,
flag
;
flag
=
set_node_to_deleted
===
true
?
"
deleted
"
:
"
available
"
;
revs_info
=
[];
selected_node
=
doctree
;
selectNode
=
function
(
node
)
{
var
i
;
if
(
node
.
rev
!==
undefined
)
{
// node is not root
revs_info
.
unshift
({
"
rev
"
:
node
.
rev
,
"
status
"
:
node
.
status
});
}
if
(
node
.
rev
===
doc
.
_rev
)
{
selected_node
=
node
;
return
"
node_selected
"
;
}
for
(
i
=
0
;
i
<
node
.
children
.
length
;
i
+=
1
)
{
if
(
selectNode
(
node
.
children
[
i
])
===
"
node_selected
"
)
{
return
"
node_selected
"
;
}
}
revs_info
.
shift
();
}
};
if
(
typeof
doc
.
_rev
===
"
string
"
)
{
// document has a previous revision
if
(
selectNode
(
selected_node
)
!==
"
node_selected
"
)
{
// no node was selected, so add a node with a specific rev
revs_info
.
unshift
({
revs_info
.
unshift
({
"
rev
"
:
next_rev
.
join
(
'
-
'
)
,
"
rev
"
:
doc
.
_rev
,
"
status
"
:
flag
"
status
"
:
"
missing
"
});
});
selected_node
.
children
.
unshift
({
selected_node
.
children
.
unshift
({
"
rev
"
:
next_rev
.
join
(
'
-
'
)
,
"
rev
"
:
doc
.
_rev
,
"
status
"
:
flag
,
"
status
"
:
"
missing
"
,
"
children
"
:
[]
"
children
"
:
[]
});
});
selected_node
=
selected_node
.
children
[
0
];
}
}
next_rev
=
priv
.
generateNextRevision
(
doc
.
_rev
||
0
,
doc
,
priv
.
revsInfoToHistory
(
revs_info
),
set_node_to_deleted
);
next_rev_str
=
next_rev
.
join
(
"
-
"
);
// 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
"
:
flag
});
if
(
selected_node
.
children
[
i
].
status
!==
flag
)
{
selected_node
.
children
[
i
].
status
=
flag
;
}
return
revs_info
;
return
revs_info
;
}
}
revs_info
.
unshift
({
"
rev
"
:
next_rev
.
join
(
'
-
'
),
"
status
"
:
flag
});
selected_node
.
children
.
unshift
({
"
rev
"
:
next_rev
.
join
(
'
-
'
),
"
status
"
:
flag
,
"
children
"
:
[]
});
return
revs_info
;
};
/**
* Gets an array of leaves revisions from document tree
* @method getLeavesFromDocumentTree
* @param {object} document_tree The document tree
* @param {string} except The revision to except
* @return {array} The array of leaves revisions
*/
priv
.
getLeavesFromDocumentTree
=
function
(
document_tree
,
except
)
{
var
result
,
search
;
result
=
[];
// search method fills [result] with the winner revision
search
=
function
(
document_tree
)
{
var
i
;
if
(
except
!==
undefined
&&
except
===
document_tree
.
rev
)
{
return
;
}
if
(
document_tree
.
children
.
length
===
0
&&
document_tree
.
status
!==
"
deleted
"
)
{
// This node is a leaf
result
.
push
(
document_tree
.
rev
);
return
;
}
// This node has children
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
// searching deeper to find the deeper leaf
search
(
document_tree
.
children
[
i
]);
}
};
};
search
(
document_tree
);
/**
return
result
;
* Gets an array of leaves revisions from document tree
};
* @method getLeavesFromDocumentTree
* @param {object} document_tree The document tree
/**
* @param {string} except The revision to except
* Check if revision is a leaf
* @return {array} The array of leaves revisions
* @method isRevisionALeaf
*/
* @param {string} revision revision to check
priv
.
getLeavesFromDocumentTree
=
function
(
document_tree
,
except
)
{
* @param {array} leaves all leaves on tree
var
i
,
result
,
search
;
* @return {boolean} true/false
result
=
[];
*/
// search method fills [result] with the winner revision
priv
.
isRevisionALeaf
=
function
(
document_tree
,
revision
)
{
search
=
function
(
document_tree
)
{
var
result
,
search
;
var
i
;
result
=
undefined
;
if
(
except
!==
undefined
&&
except
===
document_tree
.
rev
)
{
// search method fills "result" with the good revs info
return
;
search
=
function
(
document_tree
)
{
}
var
i
;
if
(
document_tree
.
children
.
length
===
0
&&
if
(
document_tree
.
rev
!==
undefined
)
{
document_tree
.
status
!==
"
deleted
"
)
{
// node is not root
// This node is a leaf
if
(
document_tree
.
rev
===
revision
)
{
result
.
push
(
document_tree
.
rev
);
if
(
document_tree
.
children
.
length
===
0
)
{
return
;
// This node is a leaf
}
result
=
true
;
// This node has children
return
;
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
}
// searching deeper to find the deeper leaf
result
=
false
;
search
(
document_tree
.
children
[
i
]);
return
;
}
};
search
(
document_tree
);
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
(
document_tree
,
revision
)
{
var
i
,
result
,
search
;
result
=
undefined
;
// search method fills "result" with the good revs info
search
=
function
(
document_tree
)
{
var
i
;
if
(
typeof
document_tree
.
rev
!==
"
undefined
"
)
{
// node is not root
if
(
document_tree
.
rev
===
revision
)
{
if
(
document_tree
.
children
.
length
===
0
)
{
// This node is a leaf
result
=
true
return
;
}
result
=
false
;
return
;
}
}
// This node has children
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
// searching deeper to find the good rev
search
(
document_tree
.
children
[
i
]);
if
(
result
!==
undefined
)
{
// The result is already found
return
;
}
}
};
search
(
document_tree
);
return
result
||
false
;
};
/**
* Convert revs_info to a simple revisions history
* @method revsInfoToHistory
* @param {array} revs_info The revs info
* @return {object} The revisions history
*/
priv
.
revsInfoToHistory
=
function
(
revs_info
)
{
var
revisions
=
{
"
start
"
:
0
,
"
ids
"
:[]},
i
;
if
(
revs_info
.
length
>
0
)
{
revisions
.
start
=
parseInt
(
revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
],
10
);
}
for
(
i
=
0
;
i
<
revs_info
.
length
;
i
+=
1
)
{
revisions
.
ids
.
push
(
revs_info
[
i
].
rev
.
split
(
'
-
'
)[
1
]);
}
}
return
revisions
;
}
};
// This node has children
for
(
i
=
0
;
i
<
document_tree
.
children
.
length
;
i
+=
1
)
{
/**
// searching deeper to find the good rev
* Returns the revision of the revision position from a revs_info array.
search
(
document_tree
.
children
[
i
]);
* @method getRevisionFromPosition
if
(
result
!==
undefined
)
{
* @param {array} revs_info The revs_info array
// The result is already found
* @param {number} rev_pos The revision position number
return
;
* @return {string} The revision of the good position (empty string if fail)
*/
priv
.
getRevisionFromPosition
=
function
(
revs_info
,
rev_pos
)
{
var
i
;
for
(
i
=
revs_info
.
length
-
1
;
i
>=
0
;
i
-=
1
)
{
if
(
priv
.
revisionToArray
(
revs_info
[
i
].
rev
)[
0
]
===
rev_pos
)
{
return
revs_info
[
i
].
rev
;
}
}
}
return
''
;
}
};
};
search
(
document_tree
);
/**
return
result
||
false
;
* Post the document metadata and create or update a document tree.
};
* Options:
* - {boolean} keep_revision_history To keep the previous revisions
/**
* (false by default) (NYI).
* Convert revs_info to a simple revisions history
* @method post
* @method revsInfoToHistory
* @param {object} command The JIO command
* @param {array} revs_info The revs info
*/
* @return {object} The revisions history
that
.
post
=
function
(
command
)
{
*/
var
f
=
{},
doctree
,
revs_info
,
doc
,
docid
;
priv
.
revsInfoToHistory
=
function
(
revs_info
)
{
doc
=
command
.
cloneDoc
();
var
revisions
=
{
docid
=
command
.
getDocId
();
"
start
"
:
0
,
"
ids
"
:
[]
if
(
typeof
doc
.
_rev
===
"
string
"
&&
},
i
;
!
priv
.
checkRevisionFormat
(
doc
.
_rev
))
{
if
(
revs_info
.
length
>
0
)
{
revisions
.
start
=
parseInt
(
revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
],
10
);
}
for
(
i
=
0
;
i
<
revs_info
.
length
;
i
+=
1
)
{
revisions
.
ids
.
push
(
revs_info
[
i
].
rev
.
split
(
'
-
'
)[
1
]);
}
return
revisions
;
};
/**
* Returns the revision of the revision position from a revs_info array.
* @method getRevisionFromPosition
* @param {array} revs_info The revs_info array
* @param {number} rev_pos The revision position number
* @return {string} The revision of the good position (empty string if fail)
*/
priv
.
getRevisionFromPosition
=
function
(
revs_info
,
rev_pos
)
{
var
i
;
for
(
i
=
revs_info
.
length
-
1
;
i
>=
0
;
i
-=
1
)
{
if
(
priv
.
revisionToArray
(
revs_info
[
i
].
rev
)[
0
]
===
rev_pos
)
{
return
revs_info
[
i
].
rev
;
}
}
return
''
;
};
/**
* Post the document metadata and create or update a document tree.
* Options:
* - {boolean} keep_revision_history To keep the previous revisions
* (false by default) (NYI).
* @method post
* @param {object} command The JIO command
*/
that
.
post
=
function
(
command
)
{
var
f
=
{},
doctree
,
revs_info
,
doc
,
docid
;
doc
=
command
.
cloneDoc
();
docid
=
command
.
getDocId
();
if
(
typeof
doc
.
_rev
===
"
string
"
&&
!
priv
.
checkRevisionFormat
(
doc
.
_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
;
}
if
(
typeof
docid
!==
"
string
"
)
{
doc
.
_id
=
priv
.
generateUuid
();
docid
=
doc
.
_id
;
}
if
(
priv
.
update_doctree_allowed
===
undefined
)
{
priv
.
update_doctree_allowed
=
true
;
}
f
.
getDocumentTree
=
function
()
{
var
option
=
command
.
cloneOption
();
if
(
option
.
max_retry
===
0
)
{
option
.
max_retry
=
3
;
}
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
docid
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
doctree
=
response
;
if
(
priv
.
update_doctree_allowed
)
{
f
.
postDocument
(
"
put
"
);
}
else
{
that
.
error
({
that
.
error
({
"
status
"
:
31
,
"
status
"
:
409
,
"
statusText
"
:
"
Wrong Revision Format
"
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
wrong_revision_format
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
The document previous revision does not match
"
+
"
message
"
:
"
Cannot update a document
"
,
"
^[0-9]+-[0-9a-zA-Z]+$
"
,
"
reason
"
:
"
Document update conflict
"
"
reason
"
:
"
Previous revision is wrong
"
});
});
return
;
}
}
},
if
(
typeof
docid
!==
"
string
"
)
{
function
(
err
)
{
doc
.
_id
=
priv
.
generateUuid
();
switch
(
err
.
status
)
{
docid
=
doc
.
_id
;
case
404
:
doctree
=
priv
.
createDocumentTree
();
f
.
postDocument
(
"
post
"
);
break
;
default
:
err
.
message
=
"
Cannot get document revision tree
"
;
that
.
error
(
err
);
break
;
}
}
}
if
(
priv
.
update_doctree_allowed
===
undefined
)
{
);
priv
.
update_doctree_allowed
=
true
;
}
f
.
getDocumentTree
=
function
()
{
var
option
=
command
.
cloneOption
();
if
(
option
[
"
max_retry
"
]
===
0
)
{
option
[
"
max_retry
"
]
=
3
;
}
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
docid
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
doctree
=
response
;
if
(
priv
.
update_doctree_allowed
)
{
f
.
postDocument
(
"
put
"
);
}
else
{
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Cannot update a document
"
,
"
reason
"
:
"
Document update conflict
"
});
}
},
function
(
err
)
{
switch
(
err
.
status
)
{
case
404
:
doctree
=
priv
.
createDocumentTree
();
f
.
postDocument
(
"
post
"
);
break
;
default
:
err
.
message
=
"
Cannot get document revision tree
"
;
that
.
error
(
err
);
break
;
}
}
);
};
f
.
postDocument
=
function
(
doctree_update_method
)
{
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
doc
);
doc
.
_id
=
docid
+
"
.
"
+
revs_info
[
0
].
rev
;
that
.
addJob
(
"
post
"
,
priv
.
substorage
,
doc
,
command
.
cloneOption
(),
function
(
response
)
{
f
.
sendDocumentTree
(
doctree_update_method
);
},
function
(
err
)
{
switch
(
err
.
status
)
{
case
409
:
// file already exists
f
.
sendDocumentTree
(
doctree_update_method
);
break
;
default
:
err
.
message
=
"
Cannot upload document
"
.
that
.
error
(
err
);
break
;
}
}
);
};
f
.
sendDocumentTree
=
function
(
method
)
{
doctree
.
_id
=
docid
+
priv
.
doctree_suffix
;
that
.
addJob
(
method
,
priv
.
substorage
,
doctree
,
command
.
cloneOption
(),
function
(
response
)
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
docid
,
"
rev
"
:
revs_info
[
0
].
rev
});
},
function
(
err
)
{
// xxx do we try to delete the posted document ?
err
.
message
=
"
Cannot save document revision tree
"
;
that
.
error
(
err
);
}
);
};
f
.
getDocumentTree
();
};
};
f
.
postDocument
=
function
(
doctree_update_method
)
{
/**
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
doc
);
* Update the document metadata and update a document tree.
doc
.
_id
=
docid
+
"
.
"
+
revs_info
[
0
].
rev
;
* Options:
that
.
addJob
(
* - {boolean} keep_revision_history To keep the previous revisions
"
post
"
,
* (false by default) (NYI).
priv
.
substorage
,
* @method put
doc
,
* @param {object} command The JIO command
command
.
cloneOption
(),
*/
function
()
{
that
.
put
=
function
(
command
)
{
f
.
sendDocumentTree
(
doctree_update_method
);
if
(
command
.
cloneDoc
().
_rev
===
undefined
)
{
},
priv
.
update_doctree_allowed
=
false
;
function
(
err
)
{
switch
(
err
.
status
)
{
case
409
:
// file already exists
f
.
sendDocumentTree
(
doctree_update_method
);
break
;
default
:
err
.
message
=
"
Cannot upload document
"
;
that
.
error
(
err
);
break
;
}
}
}
that
.
post
(
command
);
);
};
};
f
.
sendDocumentTree
=
function
(
method
)
{
/**
doctree
.
_id
=
docid
+
priv
.
doctree_suffix
;
* Get the document metadata or attachment.
that
.
addJob
(
* Options:
method
,
* - {boolean} revs Add simple revision history (false by default).
priv
.
substorage
,
* - {boolean} revs_info Add revs info (false by default).
doctree
,
* - {boolean} conflicts Add conflict object (false by default).
command
.
cloneOption
(),
* @method get
function
()
{
* @param {object} command The JIO command
that
.
success
({
*/
"
ok
"
:
true
,
that
.
get
=
function
(
command
)
{
"
id
"
:
docid
,
var
f
=
{},
doctree
,
revs_info
,
prev_rev
,
option
;
"
rev
"
:
revs_info
[
0
].
rev
option
=
command
.
cloneOption
();
});
if
(
option
[
"
max_retry
"
]
===
0
)
{
},
option
[
"
max_retry
"
]
=
3
;
function
(
err
)
{
}
// xxx do we try to delete the posted document ?
prev_rev
=
command
.
getOption
(
"
rev
"
);
err
.
message
=
"
Cannot save document revision tree
"
;
if
(
typeof
prev_rev
===
"
string
"
)
{
that
.
error
(
err
);
if
(
!
priv
.
checkRevisionFormat
(
prev_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
;
}
}
f
.
getDocumentTree
=
function
()
{
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
command
.
getDocId
()
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
doctree
=
response
;
if
(
prev_rev
===
undefined
)
{
revs_info
=
priv
.
getWinnerRevisionFromDocumentTree
(
doctree
);
prev_rev
=
revs_info
[
0
].
rev
;
}
else
{
revs_info
=
priv
.
getRevisionFromDocumentTree
(
doctree
,
prev_rev
);
}
f
.
getDocument
(
command
.
getDocId
()
+
"
.
"
+
prev_rev
,
command
.
getAttachmentId
());
},
function
(
err
)
{
switch
(
err
.
status
)
{
case
404
:
that
.
error
(
err
);
break
;
default
:
err
.
message
=
"
Cannot get document revision tree
"
;
that
.
error
(
err
);
break
;
}
}
);
};
f
.
getDocument
=
function
(
docid
,
attmtid
)
{
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
docid
,
option
,
function
(
response
)
{
var
attmt
;
if
(
typeof
response
!==
"
string
"
)
{
if
(
attmtid
!==
undefined
)
{
if
(
response
.
_attachments
!==
undefined
)
{
attmt
=
response
.
_attachments
[
attmtid
];
if
(
attmt
!==
undefined
)
{
prev_rev
=
priv
.
getRevisionFromPosition
(
revs_info
,
attmt
.
revpos
);
f
.
getDocument
(
command
.
getDocId
()
+
"
.
"
+
prev_rev
+
"
/
"
+
attmtid
);
return
;
}
}
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Cannot find the attachment
"
,
"
reason
"
:
"
Attachment is missing
"
});
return
;
}
response
.
_id
=
command
.
getDocId
();
response
.
_rev
=
prev_rev
;
if
(
command
.
getOption
(
"
revs
"
)
===
true
)
{
response
.
_revisions
=
priv
.
revsInfoToHistory
(
revs_info
);
}
if
(
command
.
getOption
(
"
revs_info
"
)
===
true
)
{
response
.
_revs_info
=
revs_info
;
}
if
(
command
.
getOption
(
"
conflicts
"
)
===
true
)
{
response
.
_conflicts
=
priv
.
getLeavesFromDocumentTree
(
doctree
,
prev_rev
);
if
(
response
.
_conflicts
.
length
===
0
)
{
delete
response
.
_conflicts
;
}
}
}
that
.
success
(
response
);
},
function
(
err
)
{
that
.
error
(
err
);
}
);
};
if
(
command
.
getAttachmentId
()
&&
prev_rev
!==
undefined
)
{
f
.
getDocument
(
command
.
getDocId
()
+
"
.
"
+
prev_rev
+
"
/
"
+
command
.
getAttachmentId
());
}
else
{
f
.
getDocumentTree
();
}
}
);
};
};
f
.
getDocumentTree
();
/**
};
* Remove document or attachment.
* Options:
/**
* - {boolean} keep_revision_history To keep the previous revisions
* Update the document metadata and update a document tree.
* @method remove
* Options:
* @param {object} command The JIO command
* - {boolean} keep_revision_history To keep the previous revisions
*/
* (false by default) (NYI).
that
.
remove
=
function
(
command
)
{
* @method put
var
f
=
{},
del_rev
,
option
,
new_doc
,
revs_info
,
new_id
;
* @param {object} command The JIO command
option
=
command
.
cloneOption
();
*/
if
(
option
[
"
max_retry
"
]
===
0
)
{
that
.
put
=
function
(
command
)
{
option
[
"
max_retry
"
]
=
3
;
if
(
command
.
cloneDoc
().
_rev
===
undefined
)
{
priv
.
update_doctree_allowed
=
false
;
}
that
.
post
(
command
);
};
/**
* Get the document metadata or attachment.
* 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
* @param {object} command The JIO command
*/
that
.
get
=
function
(
command
)
{
var
f
=
{},
doctree
,
revs_info
,
prev_rev
,
option
;
option
=
command
.
cloneOption
();
if
(
option
.
max_retry
===
0
)
{
option
.
max_retry
=
3
;
}
prev_rev
=
command
.
getOption
(
"
rev
"
);
if
(
typeof
prev_rev
===
"
string
"
)
{
if
(
!
priv
.
checkRevisionFormat
(
prev_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
;
}
}
f
.
getDocumentTree
=
function
()
{
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
command
.
getDocId
()
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
doctree
=
response
;
if
(
prev_rev
===
undefined
)
{
revs_info
=
priv
.
getWinnerRevisionFromDocumentTree
(
doctree
);
prev_rev
=
revs_info
[
0
].
rev
;
}
else
{
revs_info
=
priv
.
getRevisionFromDocumentTree
(
doctree
,
prev_rev
);
}
f
.
getDocument
(
command
.
getDocId
()
+
"
.
"
+
prev_rev
,
command
.
getAttachmentId
());
},
function
(
err
)
{
switch
(
err
.
status
)
{
case
404
:
that
.
error
(
err
);
break
;
default
:
err
.
message
=
"
Cannot get document revision tree
"
;
that
.
error
(
err
);
break
;
}
}
}
del_rev
=
command
.
getDoc
().
_rev
;
);
};
f
.
removeDocument
=
function
(
docid
,
doctree
)
{
f
.
getDocument
=
function
(
docid
,
attmtid
)
{
if
(
command
.
getOption
(
"
keep_revision_history
"
)
!==
true
)
{
that
.
addJob
(
if
(
command
.
getAttachmentId
()
===
undefined
){
"
get
"
,
// update tree
priv
.
substorage
,
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
docid
,
command
.
getDoc
(),
true
);
option
,
function
(
response
)
{
// remove revision
var
attmt
;
that
.
addJob
(
if
(
typeof
response
!==
"
string
"
)
{
"
remove
"
,
if
(
attmtid
!==
undefined
)
{
priv
.
substorage
,
if
(
response
.
_attachments
!==
undefined
)
{
docid
,
attmt
=
response
.
_attachments
[
attmtid
];
option
,
if
(
attmt
!==
undefined
)
{
function
(
response
)
{
prev_rev
=
priv
.
getRevisionFromPosition
(
// put tree
revs_info
,
doctree
.
_id
=
command
.
getDocId
()
+
attmt
.
revpos
priv
.
doctree_suffix
;
);
that
.
addJob
(
f
.
getDocument
(
command
.
getDocId
()
+
"
.
"
+
prev_rev
+
"
/
"
+
"
put
"
,
attmtid
);
priv
.
substorage
,
return
;
doctree
,
command
.
cloneOption
(),
function
(
response
)
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
(),
"
rev
"
:
revs_info
[
0
].
rev
});
},
function
(
err
){
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Cannot update document tree
"
});
return
;
}
);
},
function
(
err
)
{
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
File not found
"
,
"
reason
"
:
"
Document was not found
"
});
return
;
}
);
}
else
{
// get previsous document
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
command
.
getDocId
()
+
"
.
"
+
del_rev
,
option
,
function
(
response
)
{
// update tree
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
command
.
getDoc
());
new_doc
=
response
;
delete
new_doc
.
_attachments
;
new_doc
.
_id
=
new_doc
.
_id
+
"
.
"
+
revs_info
[
0
].
rev
;
// post new document version
that
.
addJob
(
"
post
"
,
priv
.
substorage
,
new_doc
,
command
.
cloneOption
(),
function
(
response
)
{
// put tree
doctree
.
_id
=
command
.
getDocId
()
+
priv
.
doctree_suffix
;
that
.
addJob
(
"
put
"
,
priv
.
substorage
,
doctree
,
command
.
cloneOption
(),
function
(
response
)
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
new_doc
.
_id
,
"
rev
"
:
revs_info
[
0
].
rev
});
},
function
(
err
)
{
err
.
message
=
"
Cannot save document revision tree
"
;
that
.
error
(
err
);
}
);
},
function
(
err
){
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Cannot update document
"
});
return
;
}
);
},
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
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Cannot find the attachment
"
,
"
reason
"
:
"
Attachment is missing
"
});
return
;
}
}
};
response
.
_id
=
command
.
getDocId
();
if
(
typeof
del_rev
===
"
string
"
)
{
response
.
_rev
=
prev_rev
;
if
(
!
priv
.
checkRevisionFormat
(
del_rev
))
{
if
(
command
.
getOption
(
"
revs
"
)
===
true
)
{
that
.
error
({
response
.
_revisions
=
priv
.
revsInfoToHistory
(
revs_info
);
"
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
;
}
}
if
(
command
.
getOption
(
"
revs_info
"
)
===
true
)
{
response
.
_revs_info
=
revs_info
;
}
if
(
command
.
getOption
(
"
conflicts
"
)
===
true
)
{
response
.
_conflicts
=
priv
.
getLeavesFromDocumentTree
(
doctree
,
prev_rev
);
if
(
response
.
_conflicts
.
length
===
0
)
{
delete
response
.
_conflicts
;
}
}
}
that
.
success
(
response
);
},
function
(
err
)
{
that
.
error
(
err
);
}
}
);
// get doctree
};
that
.
addJob
(
if
(
command
.
getAttachmentId
()
&&
prev_rev
!==
undefined
)
{
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
,
new_doc
,
revs_info
;
option
=
command
.
cloneOption
();
if
(
option
.
max_retry
===
0
)
{
option
.
max_retry
=
3
;
}
del_rev
=
command
.
getDoc
().
_rev
;
f
.
removeDocument
=
function
(
docid
,
doctree
)
{
if
(
command
.
getOption
(
"
keep_revision_history
"
)
!==
true
)
{
if
(
command
.
getAttachmentId
()
===
undefined
)
{
// update tree
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
command
.
getDoc
(),
true
);
// remove revision
that
.
addJob
(
"
remove
"
,
priv
.
substorage
,
docid
,
option
,
function
()
{
// put tree
doctree
.
_id
=
command
.
getDocId
()
+
priv
.
doctree_suffix
;
that
.
addJob
(
"
put
"
,
priv
.
substorage
,
doctree
,
command
.
cloneOption
(),
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
(),
"
rev
"
:
revs_info
[
0
].
rev
});
},
function
()
{
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Cannot update document tree
"
});
return
;
}
);
},
function
()
{
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
File not found
"
,
"
reason
"
:
"
Document was not found
"
});
return
;
}
);
}
else
{
// get previsous document
that
.
addJob
(
"
get
"
,
"
get
"
,
priv
.
substorage
,
priv
.
substorage
,
command
.
getDocId
()
+
priv
.
doctree_suffix
,
command
.
getDocId
()
+
"
.
"
+
del_rev
,
option
,
option
,
function
(
response
)
{
function
(
response
)
{
response
.
_conflicts
=
priv
.
getLeavesFromDocumentTree
(
response
);
// update tree
revs_info
=
priv
.
postToDocumentTree
(
doctree
,
command
.
getDoc
());
if
(
del_rev
===
undefined
)
{
new_doc
=
response
;
// no revision provided
delete
new_doc
.
_attachments
;
that
.
error
({
new_doc
.
_id
=
new_doc
.
_id
+
"
.
"
+
revs_info
[
0
].
rev
;
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
// post new document version
"
error
"
:
"
conflict
"
,
that
.
addJob
(
"
message
"
:
"
Document update conflict.
"
,
"
post
"
,
"
reason
"
:
"
Cannot delete a document without revision
"
priv
.
substorage
,
});
new_doc
,
return
;
command
.
cloneOption
(),
}
else
{
function
()
{
// revision provided
// put tree
if
(
priv
.
isRevisionALeaf
(
response
,
del_rev
)
===
true
){
doctree
.
_id
=
command
.
getDocId
()
+
priv
.
doctree_suffix
;
if
(
typeof
command
.
getAttachmentId
()
===
"
string
"
){
that
.
addJob
(
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
del_rev
+
"
put
"
,
"
/
"
+
command
.
getAttachmentId
(),
response
);
priv
.
substorage
,
}
else
{
doctree
,
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
del_rev
,
command
.
cloneOption
(),
response
function
()
{
);
that
.
success
({
}
"
ok
"
:
true
,
}
else
{
"
id
"
:
new_doc
.
_id
,
that
.
error
({
"
rev
"
:
revs_info
[
0
].
rev
"
status
"
:
409
,
});
"
statusText
"
:
"
Conflict
"
,
},
"
error
"
:
"
conflict
"
,
function
(
err
)
{
"
message
"
:
"
Document update conflict.
"
,
err
.
message
=
"
reason
"
:
"
Trying to remove non-latest revision
"
"
Cannot save document revision tree
"
;
});
that
.
error
(
err
);
return
;
}
}
);
},
function
()
{
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Cannot update document
"
});
return
;
}
}
);
},
},
function
(
err
)
{
function
()
{
that
.
error
({
that
.
error
({
"
status
"
:
404
,
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Document tree not found, please checkdocument ID
"
,
"
message
"
:
"
File not found
"
,
"
reason
"
:
"
Incorrect document ID
"
"
reason
"
:
"
Document was not found
"
});
});
return
;
return
;
}
}
);
);
}
}
};
};
if
(
typeof
del_rev
===
"
string
"
)
{
/**
if
(
!
priv
.
checkRevisionFormat
(
del_rev
))
{
* Get all documents
that
.
error
({
* @method allDocs
"
status
"
:
31
,
* @param {object} command The JIO command
"
statusText
"
:
"
Wrong Revision Format
"
,
*/
"
error
"
:
"
wrong_revision_format
"
,
that
.
allDocs
=
function
(
command
)
{
"
message
"
:
"
The document previous revision does not match
"
+
setTimeout
(
function
()
{
"
[0-9]+-[0-9a-zA-Z]+
"
,
that
.
error
({
"
reason
"
:
"
Previous revision is wrong
"
"
status
"
:
405
,
"
statusText
"
:
"
Method Not Allowed
"
,
"
error
"
:
"
method_not_allowed
"
,
"
message
"
:
"
Your are not allowed to use this command
"
,
"
reason
"
:
"
LocalStorage forbids AllDocs command executions
"
});
});
});
};
return
;
}
return
that
;
}
});
// get doctree
that
.
addJob
(
"
get
"
,
priv
.
substorage
,
command
.
getDocId
()
+
priv
.
doctree_suffix
,
option
,
function
(
response
)
{
response
.
_conflicts
=
priv
.
getLeavesFromDocumentTree
(
response
);
if
(
del_rev
===
undefined
)
{
// no revision provided
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Cannot delete a document without revision
"
});
return
;
}
// revision provided
if
(
priv
.
isRevisionALeaf
(
response
,
del_rev
)
===
true
)
{
if
(
typeof
command
.
getAttachmentId
()
===
"
string
"
)
{
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
del_rev
+
"
/
"
+
command
.
getAttachmentId
(),
response
);
}
else
{
f
.
removeDocument
(
command
.
getDocId
()
+
"
.
"
+
del_rev
,
response
);
}
}
else
{
that
.
error
({
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
"
Document update conflict.
"
,
"
reason
"
:
"
Trying to remove non-latest revision
"
});
return
;
}
},
function
()
{
that
.
error
({
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
"
Document tree not found, please checkdocument ID
"
,
"
reason
"
:
"
Incorrect document ID
"
});
return
;
}
);
};
/**
* Get all documents
* @method allDocs
* @param {object} command The JIO command
*/
that
.
allDocs
=
function
()
{
setTimeout
(
function
()
{
that
.
error
({
"
status
"
:
405
,
"
statusText
"
:
"
Method Not Allowed
"
,
"
error
"
:
"
method_not_allowed
"
,
"
message
"
:
"
Your are not allowed to use this command
"
,
"
reason
"
:
"
LocalStorage forbids AllDocs command executions
"
});
});
};
return
that
;
});
\ No newline at end of file
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