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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Tristan Cavelier
jio
Commits
c1c73f90
Commit
c1c73f90
authored
Aug 06, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
revisionstorage.js amd compatible now
parent
e3d3b88f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
946 additions
and
926 deletions
+946
-926
src/jio.storage/revisionstorage.js
src/jio.storage/revisionstorage.js
+946
-926
No files found.
src/jio.storage/revisionstorage.js
View file @
c1c73f90
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global jIO: true, hex_sha256: true, setTimeout: true */
/*global jIO, hex_sha256, setTimeout, define */
/**
/**
* JIO Revision Storage.
* JIO Revision Storage.
* It manages document version and can generate conflicts.
* It manages document version and can generate conflicts.
...
@@ -9,1014 +10,1033 @@
...
@@ -9,1014 +10,1033 @@
* "sub_storage": <sub storage description>
* "sub_storage": <sub storage description>
* }
* }
*/
*/
jIO
.
addStorageType
(
"
revision
"
,
function
(
spec
,
my
)
{
// define([module_name], [dependencies], module);
(
function
(
dependencies
,
module
)
{
"
use strict
"
;
"
use strict
"
;
var
that
=
{},
priv
=
{};
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
spec
=
spec
||
{};
return
define
(
dependencies
,
module
);
that
=
my
.
basicStorage
(
spec
,
my
);
}
// ATTRIBUTES //
module
(
jIO
,
hex_sha256
);
priv
.
doc_tree_suffix
=
"
.revision_tree.json
"
;
}([
'
jio
'
,
'
sha256
'
],
function
(
jIO
,
hex_sha256
)
{
priv
.
sub_storage
=
spec
.
sub_storage
;
"
use strict
"
;
// METHODS //
/**
jIO
.
addStorageType
(
"
revision
"
,
function
(
spec
,
my
)
{
* Constructor
*/
var
that
=
{},
priv
=
{};
priv
.
RevisionStorage
=
function
()
{
spec
=
spec
||
{};
// no init
that
=
my
.
basicStorage
(
spec
,
my
);
};
// ATTRIBUTES //
priv
.
doc_tree_suffix
=
"
.revision_tree.json
"
;
/**
priv
.
sub_storage
=
spec
.
sub_storage
;
* Description to store in order to be restored later
// METHODS //
* @method specToStore
/**
* @return {object} Descriptions to store
* Constructor
*/
*/
that
.
specToStore
=
function
()
{
priv
.
RevisionStorage
=
function
()
{
return
{
// no init
"
sub_storage
"
:
priv
.
sub_storage
};
};
};
/**
* Description to store in order to be restored later
/**
* @method specToStore
* Clones an object in deep (without functions)
* @return {object} Descriptions to store
* @method clone
*/
* @param {any} object The object to clone
that
.
specToStore
=
function
()
{
* @return {any} The cloned object
*/
priv
.
clone
=
function
(
object
)
{
var
tmp
=
JSON
.
stringify
(
object
);
if
(
tmp
===
undefined
)
{
return
undefined
;
}
return
JSON
.
parse
(
tmp
);
};
/**
* 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
();
};
/**
* Generates a hash code of a string
* @method hashCode
* @param {string} string The string to hash
* @return {string} The string hash code
*/
priv
.
hashCode
=
function
(
string
)
{
return
hex_sha256
(
string
);
};
/**
* Checks a revision format
* @method checkDocumentRevisionFormat
* @param {object} doc The document object
* @return {object} null if ok, else error object
*/
priv
.
checkDocumentRevisionFormat
=
function
(
doc
)
{
var
send_error
=
function
(
message
)
{
return
{
return
{
"
status
"
:
31
,
"
sub_storage
"
:
priv
.
sub_storage
"
statusText
"
:
"
Wrong Revision Format
"
,
"
error
"
:
"
wrong_revision_format
"
,
"
message
"
:
message
,
"
reason
"
:
"
Revision is wrong
"
};
};
};
};
if
(
typeof
doc
.
_rev
===
"
string
"
)
{
if
(
/^
[
0-9
]
+-
[
0-9a-zA-Z
]
+$/
.
test
(
doc
.
_rev
)
===
false
)
{
/**
return
send_error
(
"
The document revision does not match
"
+
* Clones an object in deep (without functions)
"
^[0-9]+-[0-9a-zA-Z]+$
"
);
* @method clone
}
* @param {any} object The object to clone
}
* @return {any} The cloned object
if
(
typeof
doc
.
_revs
===
"
object
"
)
{
*/
if
(
typeof
doc
.
_revs
.
start
!==
"
number
"
||
priv
.
clone
=
function
(
object
)
{
typeof
doc
.
_revs
.
ids
!==
"
object
"
||
var
tmp
=
JSON
.
stringify
(
object
);
typeof
doc
.
_revs
.
ids
.
length
!==
"
number
"
)
{
if
(
tmp
===
undefined
)
{
return
send_error
(
"
The document revision history is not well formated
"
);
return
undefined
;
}
}
if
(
typeof
doc
.
_revs_info
===
"
object
"
)
{
if
(
typeof
doc
.
_revs_info
.
length
!==
"
number
"
)
{
return
send_error
(
"
The document revision information
"
+
"
is not well formated
"
);
}
}
};
/**
* Creates a new document tree
* @method newDocTree
* @return {object} The new document tree
*/
priv
.
newDocTree
=
function
()
{
return
{
"
children
"
:
[]};
};
/**
* 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
i
,
revisions
=
{
"
start
"
:
0
,
"
ids
"
:
[]
};
revs_info
=
revs_info
||
[];
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
;
};
/**
* Convert the revision history object to an array of revisions.
* @method revisionHistoryToList
* @param {object} revs The revision history
* @return {array} The revision array
*/
priv
.
revisionHistoryToList
=
function
(
revs
)
{
var
i
,
start
=
revs
.
start
,
new_list
=
[];
for
(
i
=
0
;
i
<
revs
.
ids
.
length
;
i
+=
1
,
start
-=
1
)
{
new_list
.
push
(
start
+
"
-
"
+
revs
.
ids
[
i
]);
}
return
new_list
;
};
/**
* Convert revision list to revs info.
* @method revisionListToRevsInfo
* @param {array} revision_list The revision list
* @param {object} doc_tree The document tree
* @return {array} The document revs info
*/
priv
.
revisionListToRevsInfo
=
function
(
revision_list
,
doc_tree
)
{
var
revisionListToRevsInfoRec
,
revs_info
=
[],
j
;
for
(
j
=
0
;
j
<
revision_list
.
length
;
j
+=
1
)
{
revs_info
.
push
({
"
rev
"
:
revision_list
[
j
],
"
status
"
:
"
missing
"
});
}
revisionListToRevsInfoRec
=
function
(
index
,
doc_tree
)
{
var
child
,
i
;
if
(
index
<
0
)
{
return
;
}
}
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
return
JSON
.
parse
(
tmp
);
child
=
doc_tree
.
children
[
i
];
};
if
(
child
.
rev
===
revision_list
[
index
])
{
revs_info
[
index
].
status
=
child
.
status
;
/**
revisionListToRevsInfoRec
(
index
-
1
,
child
);
* 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
();
};
};
revisionListToRevsInfoRec
(
revision_list
.
length
-
1
,
doc_tree
);
return
revs_info
;
/**
};
* Generates a hash code of a string
* @method hashCode
/**
* @param {string} string The string to hash
* Update a document metadata revision properties
* @return {string} The string hash code
* @method fillDocumentRevisionProperties
*/
* @param {object} doc The document object
priv
.
hashCode
=
function
(
string
)
{
* @param {object} doc_tree The document tree
return
hex_sha256
(
string
);
*/
};
priv
.
fillDocumentRevisionProperties
=
function
(
doc
,
doc_tree
)
{
if
(
doc
.
_revs_info
)
{
/**
doc
.
_revs
=
priv
.
revsInfoToHistory
(
doc
.
_revs_info
);
* Checks a revision format
}
else
if
(
doc
.
_revs
)
{
* @method checkDocumentRevisionFormat
doc
.
_revs_info
=
priv
.
revisionListToRevsInfo
(
* @param {object} doc The document object
priv
.
revisionHistoryToList
(
doc
.
_revs
),
* @return {object} null if ok, else error object
doc_tree
*/
);
priv
.
checkDocumentRevisionFormat
=
function
(
doc
)
{
}
else
if
(
doc
.
_rev
)
{
var
send_error
=
function
(
message
)
{
doc
.
_revs_info
=
priv
.
getRevisionInfo
(
doc
.
_rev
,
doc_tree
);
return
{
doc
.
_revs
=
priv
.
revsInfoToHistory
(
doc
.
_revs_info
);
"
status
"
:
31
,
}
else
{
"
statusText
"
:
"
Wrong Revision Format
"
,
doc
.
_revs_info
=
[];
"
error
"
:
"
wrong_revision_format
"
,
doc
.
_revs
=
{
"
start
"
:
0
,
"
ids
"
:
[]};
"
message
"
:
message
,
}
"
reason
"
:
"
Revision is wrong
"
if
(
doc
.
_revs
.
start
>
0
)
{
};
doc
.
_rev
=
doc
.
_revs
.
start
+
"
-
"
+
doc
.
_revs
.
ids
[
0
];
};
}
else
{
if
(
typeof
doc
.
_rev
===
"
string
"
)
{
delete
doc
.
_rev
;
if
(
/^
[
0-9
]
+-
[
0-9a-zA-Z
]
+$/
.
test
(
doc
.
_rev
)
===
false
)
{
}
return
send_error
(
"
The document revision does not match
"
+
};
"
^[0-9]+-[0-9a-zA-Z]+$
"
);
/**
* Generates the next revision of a document.
* @methode generateNextRevision
* @param {object} doc The document metadata
* @param {boolean} deleted_flag The deleted flag
* @return {array} 0:The next revision number and 1:the hash code
*/
priv
.
generateNextRevision
=
function
(
doc
,
deleted_flag
)
{
var
string
,
revision_history
,
revs_info
,
pseudo_revision
;
doc
=
priv
.
clone
(
doc
)
||
{};
revision_history
=
doc
.
_revs
;
revs_info
=
doc
.
_revs_info
;
delete
doc
.
_rev
;
delete
doc
.
_revs
;
delete
doc
.
_revs_info
;
string
=
JSON
.
stringify
(
doc
)
+
JSON
.
stringify
(
revision_history
)
+
JSON
.
stringify
(
deleted_flag
?
true
:
false
);
revision_history
.
start
+=
1
;
revision_history
.
ids
.
unshift
(
priv
.
hashCode
(
string
));
doc
.
_revs
=
revision_history
;
doc
.
_rev
=
revision_history
.
start
+
"
-
"
+
revision_history
.
ids
[
0
];
revs_info
.
unshift
({
"
rev
"
:
doc
.
_rev
,
"
status
"
:
deleted_flag
?
"
deleted
"
:
"
available
"
});
doc
.
_revs_info
=
revs_info
;
return
doc
;
};
/**
* Gets the revs info from the document tree
* @method getRevisionInfo
* @param {string} revision The revision to search for
* @param {object} doc_tree The document tree
* @return {array} The revs info
*/
priv
.
getRevisionInfo
=
function
(
revision
,
doc_tree
)
{
var
getRevisionInfoRec
;
getRevisionInfoRec
=
function
(
doc_tree
)
{
var
i
,
child
,
revs_info
;
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
child
=
doc_tree
.
children
[
i
];
if
(
child
.
rev
===
revision
)
{
return
[{
"
rev
"
:
child
.
rev
,
"
status
"
:
child
.
status
}];
}
revs_info
=
getRevisionInfoRec
(
child
);
if
(
revs_info
.
length
>
0
||
revision
===
undefined
)
{
revs_info
.
push
({
"
rev
"
:
child
.
rev
,
"
status
"
:
child
.
status
});
return
revs_info
;
}
}
}
}
return
[];
if
(
typeof
doc
.
_revs
===
"
object
"
)
{
};
if
(
typeof
doc
.
_revs
.
start
!==
"
number
"
||
return
getRevisionInfoRec
(
doc_tree
);
typeof
doc
.
_revs
.
ids
!==
"
object
"
||
};
typeof
doc
.
_revs
.
ids
.
length
!==
"
number
"
)
{
return
send_error
(
priv
.
updateDocumentTree
=
function
(
doc
,
doc_tree
)
{
"
The document revision history is not well formated
"
var
revs_info
,
updateDocumentTreeRec
,
next_rev
;
);
doc
=
priv
.
clone
(
doc
);
revs_info
=
doc
.
_revs_info
;
updateDocumentTreeRec
=
function
(
doc_tree
,
revs_info
)
{
var
i
,
child
,
info
;
if
(
revs_info
.
length
===
0
)
{
return
;
}
info
=
revs_info
.
pop
();
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
child
=
doc_tree
.
children
[
i
];
if
(
child
.
rev
===
info
.
rev
)
{
return
updateDocumentTreeRec
(
child
,
revs_info
);
}
}
}
}
doc_tree
.
children
.
unshift
({
if
(
typeof
doc
.
_revs_info
===
"
object
"
)
{
"
rev
"
:
info
.
rev
,
if
(
typeof
doc
.
_revs_info
.
length
!==
"
number
"
)
{
"
status
"
:
info
.
status
,
return
send_error
(
"
The document revision information
"
+
"
children
"
:
[]
"
is not well formated
"
);
});
}
updateDocumentTreeRec
(
doc_tree
.
children
[
0
],
revs_info
);
};
updateDocumentTreeRec
(
doc_tree
,
priv
.
clone
(
revs_info
));
};
priv
.
send
=
function
(
method
,
doc
,
option
,
callback
)
{
that
.
addJob
(
method
,
priv
.
sub_storage
,
doc
,
option
,
function
(
success
)
{
callback
(
undefined
,
success
);
},
function
(
err
)
{
callback
(
err
,
undefined
);
}
}
);
};
};
/**
priv
.
getWinnerRevsInfo
=
function
(
doc_tree
)
{
* Creates a new document tree
var
revs_info
=
[],
getWinnerRevsInfoRec
;
* @method newDocTree
getWinnerRevsInfoRec
=
function
(
doc_tree
,
tmp_revs_info
)
{
* @return {object} The new document tree
var
i
;
*/
if
(
doc_tree
.
rev
)
{
priv
.
newDocTree
=
function
()
{
tmp_revs_info
.
unshift
({
"
rev
"
:
doc_tree
.
rev
,
"
status
"
:
doc_tree
.
status
});
return
{
"
children
"
:
[]};
};
/**
* 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
i
,
revisions
=
{
"
start
"
:
0
,
"
ids
"
:
[]
};
revs_info
=
revs_info
||
[];
if
(
revs_info
.
length
>
0
)
{
revisions
.
start
=
parseInt
(
revs_info
[
0
].
rev
.
split
(
'
-
'
)[
0
],
10
);
}
}
if
(
doc_tree
.
children
.
length
===
0
)
{
for
(
i
=
0
;
i
<
revs_info
.
length
;
i
+=
1
)
{
if
(
revs_info
.
length
===
0
||
revisions
.
ids
.
push
(
revs_info
[
i
].
rev
.
split
(
'
-
'
)[
1
]);
(
revs_info
[
0
].
status
!==
"
available
"
&&
tmp_revs_info
[
0
].
status
===
"
available
"
)
||
(
tmp_revs_info
[
0
].
status
===
"
available
"
&&
revs_info
.
length
<
tmp_revs_info
.
length
))
{
revs_info
=
priv
.
clone
(
tmp_revs_info
);
}
}
}
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
return
revisions
;
getWinnerRevsInfoRec
(
doc_tree
.
children
[
i
],
tmp_revs_info
);
};
/**
* Convert the revision history object to an array of revisions.
* @method revisionHistoryToList
* @param {object} revs The revision history
* @return {array} The revision array
*/
priv
.
revisionHistoryToList
=
function
(
revs
)
{
var
i
,
start
=
revs
.
start
,
new_list
=
[];
for
(
i
=
0
;
i
<
revs
.
ids
.
length
;
i
+=
1
,
start
-=
1
)
{
new_list
.
push
(
start
+
"
-
"
+
revs
.
ids
[
i
]);
}
}
tmp_revs_info
.
shift
();
return
new_list
;
};
};
getWinnerRevsInfoRec
(
doc_tree
,
[]);
return
revs_info
;
/**
};
* Convert revision list to revs info.
* @method revisionListToRevsInfo
priv
.
getConflicts
=
function
(
revision
,
doc_tree
)
{
* @param {array} revision_list The revision list
var
conflicts
=
[],
getConflictsRec
;
* @param {object} doc_tree The document tree
getConflictsRec
=
function
(
doc_tree
)
{
* @return {array} The document revs info
var
i
;
*/
if
(
doc_tree
.
rev
===
revision
)
{
priv
.
revisionListToRevsInfo
=
function
(
revision_list
,
doc_tree
)
{
return
;
var
revisionListToRevsInfoRec
,
revs_info
=
[],
j
;
for
(
j
=
0
;
j
<
revision_list
.
length
;
j
+=
1
)
{
revs_info
.
push
({
"
rev
"
:
revision_list
[
j
],
"
status
"
:
"
missing
"
});
}
}
if
(
doc_tree
.
children
.
length
===
0
)
{
revisionListToRevsInfoRec
=
function
(
index
,
doc_tree
)
{
if
(
doc_tree
.
status
!==
"
deleted
"
)
{
var
child
,
i
;
conflicts
.
push
(
doc_tree
.
rev
);
if
(
index
<
0
)
{
return
;
}
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
child
=
doc_tree
.
children
[
i
];
if
(
child
.
rev
===
revision_list
[
index
])
{
revs_info
[
index
].
status
=
child
.
status
;
revisionListToRevsInfoRec
(
index
-
1
,
child
);
}
}
}
};
revisionListToRevsInfoRec
(
revision_list
.
length
-
1
,
doc_tree
);
return
revs_info
;
};
/**
* Update a document metadata revision properties
* @method fillDocumentRevisionProperties
* @param {object} doc The document object
* @param {object} doc_tree The document tree
*/
priv
.
fillDocumentRevisionProperties
=
function
(
doc
,
doc_tree
)
{
if
(
doc
.
_revs_info
)
{
doc
.
_revs
=
priv
.
revsInfoToHistory
(
doc
.
_revs_info
);
}
else
if
(
doc
.
_revs
)
{
doc
.
_revs_info
=
priv
.
revisionListToRevsInfo
(
priv
.
revisionHistoryToList
(
doc
.
_revs
),
doc_tree
);
}
else
if
(
doc
.
_rev
)
{
doc
.
_revs_info
=
priv
.
getRevisionInfo
(
doc
.
_rev
,
doc_tree
);
doc
.
_revs
=
priv
.
revsInfoToHistory
(
doc
.
_revs_info
);
}
else
{
doc
.
_revs_info
=
[];
doc
.
_revs
=
{
"
start
"
:
0
,
"
ids
"
:
[]};
}
}
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
if
(
doc
.
_revs
.
start
>
0
)
{
getConflictsRec
(
doc_tree
.
children
[
i
]);
doc
.
_rev
=
doc
.
_revs
.
start
+
"
-
"
+
doc
.
_revs
.
ids
[
0
];
}
else
{
delete
doc
.
_rev
;
}
}
};
};
getConflictsRec
(
doc_tree
);
return
conflicts
.
length
===
0
?
undefined
:
conflicts
;
/**
};
* Generates the next revision of a document.
* @methode generateNextRevision
priv
.
get
=
function
(
doc
,
option
,
callback
)
{
* @param {object} doc The document metadata
priv
.
send
(
"
get
"
,
doc
,
option
,
callback
);
* @param {boolean} deleted_flag The deleted flag
};
* @return {array} 0:The next revision number and 1:the hash code
priv
.
put
=
function
(
doc
,
option
,
callback
)
{
*/
priv
.
send
(
"
put
"
,
doc
,
option
,
callback
);
priv
.
generateNextRevision
=
function
(
doc
,
deleted_flag
)
{
};
var
string
,
revision_history
,
revs_info
,
pseudo_revision
;
priv
.
remove
=
function
(
doc
,
option
,
callback
)
{
doc
=
priv
.
clone
(
doc
)
||
{};
priv
.
send
(
"
remove
"
,
doc
,
option
,
callback
);
revision_history
=
doc
.
_revs
;
};
revs_info
=
doc
.
_revs_info
;
priv
.
getAttachment
=
function
(
attachment
,
option
,
callback
)
{
delete
doc
.
_rev
;
priv
.
send
(
"
getAttachment
"
,
attachment
,
option
,
callback
);
delete
doc
.
_revs
;
};
delete
doc
.
_revs_info
;
priv
.
putAttachment
=
function
(
attachment
,
option
,
callback
)
{
string
=
JSON
.
stringify
(
doc
)
+
JSON
.
stringify
(
revision_history
)
+
priv
.
send
(
"
putAttachment
"
,
attachment
,
option
,
callback
);
JSON
.
stringify
(
deleted_flag
?
true
:
false
);
};
revision_history
.
start
+=
1
;
priv
.
removeAttachment
=
function
(
attachment
,
option
,
callback
)
{
revision_history
.
ids
.
unshift
(
priv
.
hashCode
(
string
));
priv
.
send
(
"
removeAttachment
"
,
attachment
,
option
,
callback
);
doc
.
_revs
=
revision_history
;
};
doc
.
_rev
=
revision_history
.
start
+
"
-
"
+
revision_history
.
ids
[
0
];
revs_info
.
unshift
({
priv
.
getDocument
=
function
(
doc
,
option
,
callback
)
{
"
rev
"
:
doc
.
_rev
,
doc
=
priv
.
clone
(
doc
);
"
status
"
:
deleted_flag
?
"
deleted
"
:
"
available
"
doc
.
_id
=
doc
.
_id
+
"
.
"
+
doc
.
_rev
;
});
delete
doc
.
_attachment
;
doc
.
_revs_info
=
revs_info
;
delete
doc
.
_rev
;
return
doc
;
delete
doc
.
_revs
;
};
delete
doc
.
_revs_info
;
priv
.
get
(
doc
,
option
,
callback
);
/**
};
* Gets the revs info from the document tree
priv
.
putDocument
=
function
(
doc
,
option
,
callback
)
{
* @method getRevisionInfo
doc
=
priv
.
clone
(
doc
);
* @param {string} revision The revision to search for
doc
.
_id
=
doc
.
_id
+
"
.
"
+
doc
.
_rev
;
* @param {object} doc_tree The document tree
delete
doc
.
_attachment
;
* @return {array} The revs info
delete
doc
.
_data
;
*/
delete
doc
.
_mimetype
;
priv
.
getRevisionInfo
=
function
(
revision
,
doc_tree
)
{
delete
doc
.
_rev
;
var
getRevisionInfoRec
;
delete
doc
.
_revs
;
getRevisionInfoRec
=
function
(
doc_tree
)
{
delete
doc
.
_revs_info
;
var
i
,
child
,
revs_info
;
priv
.
put
(
doc
,
option
,
callback
);
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
};
child
=
doc_tree
.
children
[
i
];
if
(
child
.
rev
===
revision
)
{
priv
.
getRevisionTree
=
function
(
doc
,
option
,
callback
)
{
return
[{
"
rev
"
:
child
.
rev
,
"
status
"
:
child
.
status
}];
doc
=
priv
.
clone
(
doc
);
}
doc
.
_id
=
doc
.
_id
+
priv
.
doc_tree_suffix
;
revs_info
=
getRevisionInfoRec
(
child
);
priv
.
get
(
doc
,
option
,
callback
);
if
(
revs_info
.
length
>
0
||
revision
===
undefined
)
{
};
revs_info
.
push
({
"
rev
"
:
child
.
rev
,
"
status
"
:
child
.
status
});
return
revs_info
;
priv
.
getAttachmentList
=
function
(
doc
,
option
,
callback
)
{
}
var
attachment_id
,
dealResults
,
state
=
"
ok
"
,
result_list
=
[],
count
=
0
;
}
dealResults
=
function
(
attachment_id
,
attachment_meta
)
{
return
[];
return
function
(
err
,
attachment
)
{
};
if
(
state
!==
"
ok
"
)
{
return
getRevisionInfoRec
(
doc_tree
);
};
priv
.
updateDocumentTree
=
function
(
doc
,
doc_tree
)
{
var
revs_info
,
updateDocumentTreeRec
,
next_rev
;
doc
=
priv
.
clone
(
doc
);
revs_info
=
doc
.
_revs_info
;
updateDocumentTreeRec
=
function
(
doc_tree
,
revs_info
)
{
var
i
,
child
,
info
;
if
(
revs_info
.
length
===
0
)
{
return
;
return
;
}
}
count
-=
1
;
info
=
revs_info
.
pop
();
if
(
err
)
{
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
if
(
err
.
status
===
404
)
{
child
=
doc_tree
.
children
[
i
];
result_list
.
push
(
undefined
);
if
(
child
.
rev
===
info
.
rev
)
{
}
else
{
return
updateDocumentTreeRec
(
child
,
revs_info
);
state
=
"
error
"
;
return
callback
(
err
,
undefined
);
}
}
}
}
result_list
.
push
({
doc_tree
.
children
.
unshift
({
"
_attachment
"
:
attachment_id
,
"
rev
"
:
info
.
rev
,
"
_data
"
:
attachment
,
"
status
"
:
info
.
status
,
"
_mimetype
"
:
attachment_meta
.
content_type
"
children
"
:
[]
});
});
if
(
count
===
0
)
{
updateDocumentTreeRec
(
doc_tree
.
children
[
0
],
revs_info
);
state
=
"
finished
"
;
};
callback
(
undefined
,
result_list
);
updateDocumentTreeRec
(
doc_tree
,
priv
.
clone
(
revs_info
));
};
priv
.
send
=
function
(
method
,
doc
,
option
,
callback
)
{
that
.
addJob
(
method
,
priv
.
sub_storage
,
doc
,
option
,
function
(
success
)
{
callback
(
undefined
,
success
);
},
function
(
err
)
{
callback
(
err
,
undefined
);
}
}
);
};
priv
.
getWinnerRevsInfo
=
function
(
doc_tree
)
{
var
revs_info
=
[],
getWinnerRevsInfoRec
;
getWinnerRevsInfoRec
=
function
(
doc_tree
,
tmp_revs_info
)
{
var
i
;
if
(
doc_tree
.
rev
)
{
tmp_revs_info
.
unshift
({
"
rev
"
:
doc_tree
.
rev
,
"
status
"
:
doc_tree
.
status
});
}
if
(
doc_tree
.
children
.
length
===
0
)
{
if
(
revs_info
.
length
===
0
||
(
revs_info
[
0
].
status
!==
"
available
"
&&
tmp_revs_info
[
0
].
status
===
"
available
"
)
||
(
tmp_revs_info
[
0
].
status
===
"
available
"
&&
revs_info
.
length
<
tmp_revs_info
.
length
))
{
revs_info
=
priv
.
clone
(
tmp_revs_info
);
}
}
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
getWinnerRevsInfoRec
(
doc_tree
.
children
[
i
],
tmp_revs_info
);
}
tmp_revs_info
.
shift
();
};
};
getWinnerRevsInfoRec
(
doc_tree
,
[]);
return
revs_info
;
};
};
for
(
attachment_id
in
doc
.
_attachments
)
{
if
(
doc
.
_attachments
.
hasOwnProperty
(
attachment_id
))
{
priv
.
getConflicts
=
function
(
revision
,
doc_tree
)
{
count
+=
1
;
var
conflicts
=
[],
getConflictsRec
;
priv
.
getAttachment
(
getConflictsRec
=
function
(
doc_tree
)
{
{
"
_id
"
:
doc
.
_id
,
"
_attachment
"
:
attachment_id
},
var
i
;
option
,
if
(
doc_tree
.
rev
===
revision
)
{
dealResults
(
attachment_id
,
doc
.
_attachments
[
attachment_id
])
);
}
}
if
(
count
===
0
)
{
callback
(
undefined
,
[]);
}
};
priv
.
putAttachmentList
=
function
(
doc
,
option
,
attachment_list
,
callback
)
{
var
i
,
dealResults
,
state
=
"
ok
"
,
count
=
0
,
attachment
;
attachment_list
=
attachment_list
||
[];
dealResults
=
function
(
index
)
{
return
function
(
err
,
response
)
{
if
(
state
!==
"
ok
"
)
{
return
;
return
;
}
}
count
-=
1
;
if
(
doc_tree
.
children
.
length
===
0
)
{
if
(
err
)
{
if
(
doc_tree
.
status
!==
"
deleted
"
)
{
state
=
"
error
"
;
conflicts
.
push
(
doc_tree
.
rev
)
;
return
callback
(
err
,
undefined
);
}
}
}
if
(
count
===
0
)
{
for
(
i
=
0
;
i
<
doc_tree
.
children
.
length
;
i
+=
1
)
{
state
=
"
finished
"
;
getConflictsRec
(
doc_tree
.
children
[
i
]);
callback
(
undefined
,
{
"
id
"
:
doc
.
_id
,
"
ok
"
:
true
});
}
}
};
};
getConflictsRec
(
doc_tree
);
return
conflicts
.
length
===
0
?
undefined
:
conflicts
;
};
};
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
attachment
=
attachment_list
[
i
];
priv
.
get
=
function
(
doc
,
option
,
callback
)
{
if
(
attachment
!==
undefined
)
{
priv
.
send
(
"
get
"
,
doc
,
option
,
callback
);
count
+=
1
;
attachment
.
_id
=
doc
.
_id
+
"
.
"
+
doc
.
_rev
;
priv
.
putAttachment
(
attachment
,
option
,
dealResults
(
i
));
}
}
if
(
count
===
0
)
{
return
callback
(
undefined
,
{
"
id
"
:
doc
.
_id
,
"
ok
"
:
true
});
}
};
priv
.
putDocumentTree
=
function
(
doc
,
option
,
doc_tree
,
callback
)
{
doc_tree
=
priv
.
clone
(
doc_tree
);
doc_tree
.
_id
=
doc
.
_id
+
priv
.
doc_tree_suffix
;
priv
.
put
(
doc_tree
,
option
,
callback
);
};
priv
.
notFoundError
=
function
(
message
,
reason
)
{
return
{
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
message
,
"
reason
"
:
reason
};
};
priv
.
conflictError
=
function
(
message
,
reason
)
{
return
{
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
message
,
"
reason
"
:
reason
};
};
priv
.
revisionGenericRequest
=
function
(
doc
,
option
,
specific_parameter
,
onEnd
)
{
var
prev_doc
,
doc_tree
,
attachment_list
,
callback
=
{};
if
(
specific_parameter
.
doc_id
)
{
doc
.
_id
=
specific_parameter
.
doc_id
;
}
if
(
specific_parameter
.
attachment_id
)
{
doc
.
_attachment
=
specific_parameter
.
attachment_id
;
}
callback
.
begin
=
function
()
{
var
check_error
;
doc
.
_id
=
doc
.
_id
||
priv
.
generateUuid
();
if
(
specific_parameter
.
revision_needed
&&
!
doc
.
_rev
)
{
return
onEnd
(
priv
.
conflictError
(
"
Document update conflict
"
,
"
No document revision was provided
"
),
undefined
);
}
// check revision format
check_error
=
priv
.
checkDocumentRevisionFormat
(
doc
);
if
(
check_error
!==
undefined
)
{
return
onEnd
(
check_error
,
undefined
);
}
priv
.
getRevisionTree
(
doc
,
option
,
callback
.
getRevisionTree
);
};
};
callback
.
getRevisionTree
=
function
(
err
,
response
)
{
priv
.
put
=
function
(
doc
,
option
,
callback
)
{
var
winner_info
,
previous_revision
=
doc
.
_rev
,
priv
.
send
(
"
put
"
,
doc
,
option
,
callback
);
generate_new_revision
=
doc
.
_revs
||
doc
.
_revs_info
?
false
:
true
;
};
if
(
err
)
{
priv
.
remove
=
function
(
doc
,
option
,
callback
)
{
if
(
err
.
status
!==
404
)
{
priv
.
send
(
"
remove
"
,
doc
,
option
,
callback
);
err
.
message
=
"
Cannot get document revision tree
"
;
};
return
onEnd
(
err
,
undefined
);
priv
.
getAttachment
=
function
(
attachment
,
option
,
callback
)
{
}
priv
.
send
(
"
getAttachment
"
,
attachment
,
option
,
callback
);
}
};
doc_tree
=
response
||
priv
.
newDocTree
();
priv
.
putAttachment
=
function
(
attachment
,
option
,
callback
)
{
if
(
specific_parameter
.
get
||
specific_parameter
.
getAttachment
)
{
priv
.
send
(
"
putAttachment
"
,
attachment
,
option
,
callback
);
if
(
!
doc
.
_rev
)
{
};
winner_info
=
priv
.
getWinnerRevsInfo
(
doc_tree
);
priv
.
removeAttachment
=
function
(
attachment
,
option
,
callback
)
{
if
(
winner_info
.
length
===
0
)
{
priv
.
send
(
"
removeAttachment
"
,
attachment
,
option
,
callback
);
return
onEnd
(
priv
.
notFoundError
(
};
"
Document not found
"
,
"
missing
"
priv
.
getDocument
=
function
(
doc
,
option
,
callback
)
{
),
undefined
);
doc
=
priv
.
clone
(
doc
);
doc
.
_id
=
doc
.
_id
+
"
.
"
+
doc
.
_rev
;
delete
doc
.
_attachment
;
delete
doc
.
_rev
;
delete
doc
.
_revs
;
delete
doc
.
_revs_info
;
priv
.
get
(
doc
,
option
,
callback
);
};
priv
.
putDocument
=
function
(
doc
,
option
,
callback
)
{
doc
=
priv
.
clone
(
doc
);
doc
.
_id
=
doc
.
_id
+
"
.
"
+
doc
.
_rev
;
delete
doc
.
_attachment
;
delete
doc
.
_data
;
delete
doc
.
_mimetype
;
delete
doc
.
_rev
;
delete
doc
.
_revs
;
delete
doc
.
_revs_info
;
priv
.
put
(
doc
,
option
,
callback
);
};
priv
.
getRevisionTree
=
function
(
doc
,
option
,
callback
)
{
doc
=
priv
.
clone
(
doc
);
doc
.
_id
=
doc
.
_id
+
priv
.
doc_tree_suffix
;
priv
.
get
(
doc
,
option
,
callback
);
};
priv
.
getAttachmentList
=
function
(
doc
,
option
,
callback
)
{
var
attachment_id
,
dealResults
,
state
=
"
ok
"
,
result_list
=
[],
count
=
0
;
dealResults
=
function
(
attachment_id
,
attachment_meta
)
{
return
function
(
err
,
attachment
)
{
if
(
state
!==
"
ok
"
)
{
return
;
}
}
if
(
winner_info
[
0
].
status
===
"
deleted
"
)
{
count
-=
1
;
return
onEnd
(
priv
.
notFoundError
(
if
(
err
)
{
"
Document not found
"
,
if
(
err
.
status
===
404
)
{
"
deleted
"
result_list
.
push
(
undefined
);
),
undefined
);
}
else
{
state
=
"
error
"
;
return
callback
(
err
,
undefined
);
}
}
}
doc
.
_rev
=
winner_info
[
0
].
rev
;
result_list
.
push
({
"
_attachment
"
:
attachment_id
,
"
_data
"
:
attachment
,
"
_mimetype
"
:
attachment_meta
.
content_type
});
if
(
count
===
0
)
{
state
=
"
finished
"
;
callback
(
undefined
,
result_list
);
}
};
};
for
(
attachment_id
in
doc
.
_attachments
)
{
if
(
doc
.
_attachments
.
hasOwnProperty
(
attachment_id
))
{
count
+=
1
;
priv
.
getAttachment
(
{
"
_id
"
:
doc
.
_id
,
"
_attachment
"
:
attachment_id
},
option
,
dealResults
(
attachment_id
,
doc
.
_attachments
[
attachment_id
])
);
}
}
priv
.
fillDocumentRevisionProperties
(
doc
,
doc_tree
);
return
priv
.
getDocument
(
doc
,
option
,
callback
.
getDocument
);
}
}
priv
.
fillDocumentRevisionProperties
(
doc
,
doc_tree
);
if
(
count
===
0
)
{
if
(
generate_new_revision
)
{
callback
(
undefined
,
[]);
if
(
previous_revision
&&
doc
.
_revs_info
.
length
===
0
)
{
// the document history has changed, it means that the document
// revision was wrong. Add a pseudo history to the document
doc
.
_rev
=
previous_revision
;
doc
.
_revs
=
{
"
start
"
:
parseInt
(
previous_revision
.
split
(
"
-
"
)[
0
],
10
),
"
ids
"
:
[
previous_revision
.
split
(
"
-
"
)[
1
]]
};
doc
.
_revs_info
=
[{
"
rev
"
:
previous_revision
,
"
status
"
:
"
missing
"
}];
}
doc
=
priv
.
generateNextRevision
(
doc
,
specific_parameter
.
remove
);
}
}
if
(
doc
.
_revs_info
.
length
>
1
)
{
};
prev_doc
=
{
"
_id
"
:
doc
.
_id
,
priv
.
putAttachmentList
=
function
(
doc
,
option
,
attachment_list
,
callback
)
{
"
_rev
"
:
doc
.
_revs_info
[
1
].
rev
var
i
,
dealResults
,
state
=
"
ok
"
,
count
=
0
,
attachment
;
attachment_list
=
attachment_list
||
[];
dealResults
=
function
(
index
)
{
return
function
(
err
,
response
)
{
if
(
state
!==
"
ok
"
)
{
return
;
}
count
-=
1
;
if
(
err
)
{
state
=
"
error
"
;
return
callback
(
err
,
undefined
);
}
if
(
count
===
0
)
{
state
=
"
finished
"
;
callback
(
undefined
,
{
"
id
"
:
doc
.
_id
,
"
ok
"
:
true
});
}
};
};
if
(
!
generate_new_revision
&&
specific_parameter
.
putAttachment
)
{
};
prev_doc
.
_rev
=
doc
.
_revs_info
[
0
].
rev
;
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
attachment
=
attachment_list
[
i
];
if
(
attachment
!==
undefined
)
{
count
+=
1
;
attachment
.
_id
=
doc
.
_id
+
"
.
"
+
doc
.
_rev
;
priv
.
putAttachment
(
attachment
,
option
,
dealResults
(
i
));
}
}
}
}
// force revs_info status
if
(
count
===
0
)
{
doc
.
_revs_info
[
0
].
status
=
(
specific_parameter
.
remove
?
return
callback
(
undefined
,
{
"
id
"
:
doc
.
_id
,
"
ok
"
:
true
});
"
deleted
"
:
"
available
"
);
}
priv
.
updateDocumentTree
(
doc
,
doc_tree
);
};
if
(
prev_doc
)
{
return
priv
.
getDocument
(
prev_doc
,
option
,
callback
.
getDocument
);
priv
.
putDocumentTree
=
function
(
doc
,
option
,
doc_tree
,
callback
)
{
doc_tree
=
priv
.
clone
(
doc_tree
);
doc_tree
.
_id
=
doc
.
_id
+
priv
.
doc_tree_suffix
;
priv
.
put
(
doc_tree
,
option
,
callback
);
};
priv
.
notFoundError
=
function
(
message
,
reason
)
{
return
{
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
message
"
:
message
,
"
reason
"
:
reason
};
};
priv
.
conflictError
=
function
(
message
,
reason
)
{
return
{
"
status
"
:
409
,
"
statusText
"
:
"
Conflict
"
,
"
error
"
:
"
conflict
"
,
"
message
"
:
message
,
"
reason
"
:
reason
};
};
priv
.
revisionGenericRequest
=
function
(
doc
,
option
,
specific_parameter
,
onEnd
)
{
var
prev_doc
,
doc_tree
,
attachment_list
,
callback
=
{};
if
(
specific_parameter
.
doc_id
)
{
doc
.
_id
=
specific_parameter
.
doc_id
;
}
}
if
(
specific_parameter
.
remove
||
specific_parameter
.
removeAttachment
)
{
if
(
specific_parameter
.
attachment_id
)
{
return
onEnd
(
priv
.
notFoundError
(
doc
.
_attachment
=
specific_parameter
.
attachment_id
;
"
Unable to remove an inexistent document
"
,
"
missing
"
),
undefined
);
}
}
priv
.
putDocument
(
doc
,
option
,
callback
.
putDocument
);
callback
.
begin
=
function
()
{
};
var
check_error
;
callback
.
getDocument
=
function
(
err
,
res_doc
)
{
doc
.
_id
=
doc
.
_id
||
priv
.
generateUuid
();
var
k
,
conflicts
;
if
(
specific_parameter
.
revision_needed
&&
!
doc
.
_rev
)
{
if
(
err
)
{
return
onEnd
(
priv
.
conflictError
(
if
(
err
.
status
===
404
)
{
"
Document update conflict
"
,
if
(
specific_parameter
.
remove
||
"
No document revision was provided
"
specific_parameter
.
removeAttachment
)
{
),
undefined
);
return
onEnd
(
priv
.
conflictError
(
"
Document update conflict
"
,
"
Document is missing
"
),
undefined
);
}
if
(
specific_parameter
.
get
)
{
return
onEnd
(
priv
.
notFoundError
(
"
Unable to find the document
"
,
"
missing
"
),
undefined
);
}
res_doc
=
{};
}
else
{
err
.
message
=
"
Cannot get document
"
;
return
onEnd
(
err
,
undefined
);
}
}
}
// check revision format
if
(
specific_parameter
.
get
)
{
check_error
=
priv
.
checkDocumentRevisionFormat
(
doc
);
res_doc
.
_id
=
doc
.
_id
;
if
(
check_error
!==
undefined
)
{
res_doc
.
_rev
=
doc
.
_rev
;
return
onEnd
(
check_error
,
undefined
);
if
(
option
.
conflicts
===
true
)
{
}
conflicts
=
priv
.
getConflicts
(
doc
.
_rev
,
doc_tree
);
priv
.
getRevisionTree
(
doc
,
option
,
callback
.
getRevisionTree
);
if
(
conflicts
)
{
};
res_doc
.
_conflicts
=
conflicts
;
callback
.
getRevisionTree
=
function
(
err
,
response
)
{
var
winner_info
,
previous_revision
,
generate_new_revision
;
previous_revision
=
doc
.
_rew
;
generate_new_revision
=
doc
.
_revs
||
doc
.
_revs_info
?
false
:
true
;
if
(
err
)
{
if
(
err
.
status
!==
404
)
{
err
.
message
=
"
Cannot get document revision tree
"
;
return
onEnd
(
err
,
undefined
);
}
}
}
}
if
(
option
.
revs
===
true
)
{
doc_tree
=
response
||
priv
.
newDocTree
();
res_doc
.
_revisions
=
doc
.
_revs
;
if
(
specific_parameter
.
get
||
specific_parameter
.
getAttachment
)
{
if
(
!
doc
.
_rev
)
{
winner_info
=
priv
.
getWinnerRevsInfo
(
doc_tree
);
if
(
winner_info
.
length
===
0
)
{
return
onEnd
(
priv
.
notFoundError
(
"
Document not found
"
,
"
missing
"
),
undefined
);
}
if
(
winner_info
[
0
].
status
===
"
deleted
"
)
{
return
onEnd
(
priv
.
notFoundError
(
"
Document not found
"
,
"
deleted
"
),
undefined
);
}
doc
.
_rev
=
winner_info
[
0
].
rev
;
}
priv
.
fillDocumentRevisionProperties
(
doc
,
doc_tree
);
return
priv
.
getDocument
(
doc
,
option
,
callback
.
getDocument
);
}
}
if
(
option
.
revs_info
===
true
)
{
priv
.
fillDocumentRevisionProperties
(
doc
,
doc_tree
);
res_doc
.
_revs_info
=
doc
.
_revs_info
;
if
(
generate_new_revision
)
{
if
(
previous_revision
&&
doc
.
_revs_info
.
length
===
0
)
{
// the document history has changed, it means that the document
// revision was wrong. Add a pseudo history to the document
doc
.
_rev
=
previous_revision
;
doc
.
_revs
=
{
"
start
"
:
parseInt
(
previous_revision
.
split
(
"
-
"
)[
0
],
10
),
"
ids
"
:
[
previous_revision
.
split
(
"
-
"
)[
1
]]
};
doc
.
_revs_info
=
[{
"
rev
"
:
previous_revision
,
"
status
"
:
"
missing
"
}];
}
doc
=
priv
.
generateNextRevision
(
doc
,
specific_parameter
.
remove
);
}
}
return
onEnd
(
undefined
,
res_doc
);
if
(
doc
.
_revs_info
.
length
>
1
)
{
}
prev_doc
=
{
if
(
specific_parameter
.
putAttachment
||
"
_id
"
:
doc
.
_id
,
specific_parameter
.
removeAttachment
)
{
"
_rev
"
:
doc
.
_revs_info
[
1
].
rev
// copy metadata (not beginning by "_" to document
};
for
(
k
in
res_doc
)
{
if
(
!
generate_new_revision
&&
specific_parameter
.
putAttachment
)
{
if
(
res_doc
.
hasOwnProperty
(
k
)
&&
!
k
.
match
(
"
^_
"
))
{
prev_doc
.
_rev
=
doc
.
_revs_info
[
0
].
rev
;
doc
[
k
]
=
res_doc
[
k
];
}
}
}
}
}
// force revs_info status
if
(
specific_parameter
.
remove
)
{
doc
.
_revs_info
[
0
].
status
=
(
specific_parameter
.
remove
?
priv
.
putDocumentTree
(
doc
,
option
,
doc_tree
,
callback
.
putDocumentTree
);
"
deleted
"
:
"
available
"
);
}
else
{
priv
.
updateDocumentTree
(
doc
,
doc_tree
);
priv
.
getAttachmentList
(
res_doc
,
option
,
callback
.
getAttachmentList
);
if
(
prev_doc
)
{
}
return
priv
.
getDocument
(
prev_doc
,
option
,
callback
.
getDocument
);
};
}
callback
.
getAttachmentList
=
function
(
err
,
res_list
)
{
if
(
specific_parameter
.
remove
||
specific_parameter
.
removeAttachment
)
{
var
i
,
attachment_found
=
false
;
if
(
err
)
{
err
.
message
=
"
Cannot get attachment
"
;
return
onEnd
(
err
,
undefined
);
}
attachment_list
=
res_list
||
[];
if
(
specific_parameter
.
getAttachment
)
{
// getting specific attachment
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
if
(
attachment_list
[
i
]
&&
doc
.
_attachment
===
attachment_list
[
i
].
_attachment
)
{
return
onEnd
(
undefined
,
attachment_list
[
i
].
_data
);
}
}
return
onEnd
(
priv
.
notFoundError
(
"
Unable to get an inexistent attachment
"
,
"
missing
"
),
undefined
);
}
if
(
specific_parameter
.
remove_from_attachment_list
)
{
// removing specific attachment
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
if
(
attachment_list
[
i
]
&&
specific_parameter
.
remove_from_attachment_list
.
_attachment
===
attachment_list
[
i
].
_attachment
)
{
attachment_found
=
true
;
attachment_list
[
i
]
=
undefined
;
break
;
}
}
if
(
!
attachment_found
)
{
return
onEnd
(
priv
.
notFoundError
(
return
onEnd
(
priv
.
notFoundError
(
"
Unable to remove an inexistent
attach
ment
"
,
"
Unable to remove an inexistent
docu
ment
"
,
"
missing
"
"
missing
"
),
undefined
);
),
undefined
);
}
}
}
priv
.
putDocument
(
doc
,
option
,
callback
.
putDocument
);
priv
.
putDocument
(
doc
,
option
,
callback
.
putDocument
);
};
};
callback
.
getDocument
=
function
(
err
,
res_doc
)
{
callback
.
putDocument
=
function
(
err
,
response
)
{
var
k
,
conflicts
;
var
i
,
attachment_found
=
false
;
if
(
err
)
{
if
(
err
)
{
if
(
err
.
status
===
404
)
{
err
.
message
=
"
Cannot post the document
"
;
if
(
specific_parameter
.
remove
||
return
onEnd
(
err
,
undefined
);
specific_parameter
.
removeAttachment
)
{
}
return
onEnd
(
priv
.
conflictError
(
if
(
specific_parameter
.
add_to_attachment_list
)
{
"
Document update conflict
"
,
// adding specific attachment
"
Document is missing
"
attachment_list
=
attachment_list
||
[];
),
undefined
);
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
}
if
(
attachment_list
[
i
]
&&
if
(
specific_parameter
.
get
)
{
specific_parameter
.
add_to_attachment_list
.
_attachment
===
return
onEnd
(
priv
.
notFoundError
(
attachment_list
[
i
].
_attachment
)
{
"
Unable to find the document
"
,
attachment_found
=
true
;
"
missing
"
attachment_list
[
i
]
=
specific_parameter
.
add_to_attachment_list
;
),
undefined
);
break
;
}
res_doc
=
{};
}
else
{
err
.
message
=
"
Cannot get document
"
;
return
onEnd
(
err
,
undefined
);
}
}
}
}
if
(
!
attachment_found
)
{
if
(
specific_parameter
.
get
)
{
attachment_list
.
unshift
(
specific_parameter
.
add_to_attachment_list
);
res_doc
.
_id
=
doc
.
_id
;
res_doc
.
_rev
=
doc
.
_rev
;
if
(
option
.
conflicts
===
true
)
{
conflicts
=
priv
.
getConflicts
(
doc
.
_rev
,
doc_tree
);
if
(
conflicts
)
{
res_doc
.
_conflicts
=
conflicts
;
}
}
if
(
option
.
revs
===
true
)
{
res_doc
.
_revisions
=
doc
.
_revs
;
}
if
(
option
.
revs_info
===
true
)
{
res_doc
.
_revs_info
=
doc
.
_revs_info
;
}
return
onEnd
(
undefined
,
res_doc
);
}
if
(
specific_parameter
.
putAttachment
||
specific_parameter
.
removeAttachment
)
{
// copy metadata (not beginning by "_" to document
for
(
k
in
res_doc
)
{
if
(
res_doc
.
hasOwnProperty
(
k
)
&&
!
k
.
match
(
"
^_
"
))
{
doc
[
k
]
=
res_doc
[
k
];
}
}
}
if
(
specific_parameter
.
remove
)
{
priv
.
putDocumentTree
(
doc
,
option
,
doc_tree
,
callback
.
putDocumentTree
);
}
else
{
priv
.
getAttachmentList
(
res_doc
,
option
,
callback
.
getAttachmentList
);
}
}
}
priv
.
putAttachmentList
(
doc
,
option
,
attachment_list
,
callback
.
putAttachmentList
);
};
callback
.
putAttachmentList
=
function
(
err
,
response
)
{
if
(
err
)
{
err
.
message
=
"
Cannot copy attacments to the document
"
;
return
onEnd
(
err
,
undefined
);
}
priv
.
putDocumentTree
(
doc
,
option
,
doc_tree
,
callback
.
putDocumentTree
);
};
callback
.
putDocumentTree
=
function
(
err
,
response
)
{
var
response_object
;
if
(
err
)
{
err
.
message
=
"
Cannot update the document history
"
;
return
onEnd
(
err
,
undefined
);
}
response_object
=
{
"
ok
"
:
true
,
"
id
"
:
doc
.
_id
,
"
rev
"
:
doc
.
_rev
};
};
if
(
specific_parameter
.
putAttachment
||
callback
.
getAttachmentList
=
function
(
err
,
res_list
)
{
specific_parameter
.
removeAttachment
||
var
i
,
attachment_found
=
false
;
specific_parameter
.
getAttachment
)
{
response_object
.
attachment
=
doc
.
_attachment
;
}
onEnd
(
undefined
,
response_object
);
// if (option.keep_revision_history !== true) {
// // priv.remove(prev_doc, option, function () {
// // - change "available" status to "deleted"
// // - remove attachments
// // - done, no callback
// // });
// }
};
callback
.
begin
();
};
/**
* 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
)
{
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{},
function
(
err
,
response
)
{
if
(
err
)
{
if
(
err
)
{
return
that
.
error
(
err
);
err
.
message
=
"
Cannot get attachment
"
;
return
onEnd
(
err
,
undefined
);
}
}
that
.
success
(
response
);
attachment_list
=
res_list
||
[];
}
if
(
specific_parameter
.
getAttachment
)
{
);
// getting specific attachment
};
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
if
(
attachment_list
[
i
]
&&
/**
doc
.
_attachment
===
* Put the document metadata and create or update a document tree.
attachment_list
[
i
].
_attachment
)
{
* Options:
return
onEnd
(
undefined
,
attachment_list
[
i
].
_data
);
* - {boolean} keep_revision_history To keep the previous revisions
}
* (false by default) (NYI).
}
* @method put
return
onEnd
(
priv
.
notFoundError
(
* @param {object} command The JIO command
"
Unable to get an inexistent attachment
"
,
*/
"
missing
"
that
.
put
=
function
(
command
)
{
),
undefined
);
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
}
that
.
success
(
response
);
if
(
specific_parameter
.
remove_from_attachment_list
)
{
}
// removing specific attachment
);
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
};
if
(
attachment_list
[
i
]
&&
specific_parameter
.
remove_from_attachment_list
.
_attachment
===
attachment_list
[
i
].
_attachment
)
{
that
.
putAttachment
=
function
(
command
)
{
attachment_found
=
true
;
priv
.
revisionGenericRequest
(
attachment_list
[
i
]
=
undefined
;
command
.
cloneDoc
(),
break
;
command
.
cloneOption
(),
}
{
}
"
doc_id
"
:
command
.
getDocId
(),
if
(
!
attachment_found
)
{
"
attachment_id
"
:
command
.
getAttachmentId
(),
return
onEnd
(
priv
.
notFoundError
(
"
add_to_attachment_list
"
:
{
"
Unable to remove an inexistent attachment
"
,
"
_attachment
"
:
command
.
getAttachmentId
(),
"
missing
"
"
_mimetype
"
:
command
.
getAttachmentMimeType
(),
),
undefined
);
"
_data
"
:
command
.
getAttachmentData
()
}
},
"
putAttachment
"
:
true
},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
}
that
.
success
(
response
);
priv
.
putDocument
(
doc
,
option
,
callback
.
putDocument
);
}
};
);
callback
.
putDocument
=
function
(
err
,
response
)
{
};
var
i
,
attachment_found
=
false
;
that
.
remove
=
function
(
command
)
{
if
(
command
.
getAttachmentId
())
{
return
that
.
removeAttachment
(
command
);
}
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{
"
revision_needed
"
:
true
,
"
remove
"
:
true
},
function
(
err
,
response
)
{
if
(
err
)
{
if
(
err
)
{
return
that
.
error
(
err
);
err
.
message
=
"
Cannot post the document
"
;
return
onEnd
(
err
,
undefined
);
}
}
that
.
success
(
response
);
if
(
specific_parameter
.
add_to_attachment_list
)
{
}
// adding specific attachment
);
attachment_list
=
attachment_list
||
[];
};
for
(
i
=
0
;
i
<
attachment_list
.
length
;
i
+=
1
)
{
if
(
attachment_list
[
i
]
&&
that
.
removeAttachment
=
function
(
command
)
{
specific_parameter
.
add_to_attachment_list
.
_attachment
===
priv
.
revisionGenericRequest
(
attachment_list
[
i
].
_attachment
)
{
command
.
cloneDoc
(),
attachment_found
=
true
;
command
.
cloneOption
(),
attachment_list
[
i
]
=
specific_parameter
.
add_to_attachment_list
;
{
break
;
"
doc_id
"
:
command
.
getDocId
(),
}
"
attachment_id
"
:
command
.
getAttachmentId
(),
}
"
revision_needed
"
:
true
,
if
(
!
attachment_found
)
{
"
removeAttachment
"
:
true
,
attachment_list
.
unshift
(
specific_parameter
.
add_to_attachment_list
);
"
remove_from_attachment_list
"
:
{
}
"
_attachment
"
:
command
.
getAttachmentId
()
}
},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
}
that
.
success
(
response
);
priv
.
putAttachmentList
(
}
doc
,
);
option
,
};
attachment_list
,
callback
.
putAttachmentList
that
.
get
=
function
(
command
)
{
);
if
(
command
.
getAttachmentId
())
{
};
return
that
.
getAttachment
(
command
);
callback
.
putAttachmentList
=
function
(
err
,
response
)
{
}
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{
"
get
"
:
true
},
function
(
err
,
response
)
{
if
(
err
)
{
if
(
err
)
{
return
that
.
error
(
err
);
err
.
message
=
"
Cannot copy attacments to the document
"
;
return
onEnd
(
err
,
undefined
);
}
}
that
.
success
(
response
);
priv
.
putDocumentTree
(
doc
,
option
,
doc_tree
,
callback
.
putDocumentTree
);
}
};
);
callback
.
putDocumentTree
=
function
(
err
,
response
)
{
};
var
response_object
;
that
.
getAttachment
=
function
(
command
)
{
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{
"
doc_id
"
:
command
.
getDocId
(),
"
attachment_id
"
:
command
.
getAttachmentId
(),
"
getAttachment
"
:
true
},
function
(
err
,
response
)
{
if
(
err
)
{
if
(
err
)
{
return
that
.
error
(
err
);
err
.
message
=
"
Cannot update the document history
"
;
return
onEnd
(
err
,
undefined
);
}
}
that
.
success
(
response
);
response_object
=
{
}
"
ok
"
:
true
,
);
"
id
"
:
doc
.
_id
,
};
"
rev
"
:
doc
.
_rev
};
that
.
allDocs
=
function
(
command
)
{
if
(
specific_parameter
.
putAttachment
||
var
rows
,
result
=
{
"
total_rows
"
:
0
,
"
rows
"
:
[]},
functions
=
{};
specific_parameter
.
removeAttachment
||
functions
.
finished
=
0
;
specific_parameter
.
getAttachment
)
{
functions
.
falseResponseGenerator
=
function
(
response
,
callback
)
{
response_object
.
attachment
=
doc
.
_attachment
;
callback
(
undefined
,
response
);
};
functions
.
fillResultGenerator
=
function
(
doc_id
)
{
return
function
(
err
,
doc_tree
)
{
var
document_revision
,
row
,
revs_info
;
if
(
err
)
{
return
that
.
error
(
err
);
}
}
revs_info
=
priv
.
getWinnerRevsInfo
(
doc_tree
);
onEnd
(
undefined
,
response_object
);
document_revision
=
// if (option.keep_revision_history !== true) {
rows
.
document_revisions
[
doc_id
+
"
.
"
+
revs_info
[
0
].
rev
];
// // priv.remove(prev_doc, option, function () {
if
(
document_revision
)
{
// // - change "available" status to "deleted"
row
=
{
// // - remove attachments
"
id
"
:
doc_id
,
// // - done, no callback
"
key
"
:
doc_id
,
// // });
"
value
"
:
{
// }
"
rev
"
:
revs_info
[
0
].
rev
};
}
callback
.
begin
();
};
};
if
(
document_revision
.
doc
&&
command
.
getOption
(
"
include_docs
"
))
{
document_revision
.
doc
.
_id
=
doc_id
;
/**
document_revision
.
doc
.
_rev
=
revs_info
[
0
].
rev
;
* Post the document metadata and create or update a document tree.
row
.
doc
=
document_revision
.
doc
;
* 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
)
{
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
}
result
.
rows
.
push
(
row
);
that
.
success
(
response
);
result
.
total_rows
+=
1
;
}
}
functions
.
success
();
);
};
};
/**
* Put 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 put
* @param {object} command The JIO command
*/
that
.
put
=
function
(
command
)
{
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
that
.
success
(
response
);
}
);
};
that
.
putAttachment
=
function
(
command
)
{
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{
"
doc_id
"
:
command
.
getDocId
(),
"
attachment_id
"
:
command
.
getAttachmentId
(),
"
add_to_attachment_list
"
:
{
"
_attachment
"
:
command
.
getAttachmentId
(),
"
_mimetype
"
:
command
.
getAttachmentMimeType
(),
"
_data
"
:
command
.
getAttachmentData
()
},
"
putAttachment
"
:
true
},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
that
.
success
(
response
);
}
);
};
};
functions
.
success
=
function
()
{
functions
.
finished
-=
1
;
that
.
remove
=
function
(
command
)
{
if
(
functions
.
finished
===
0
)
{
if
(
command
.
getAttachmentId
()
)
{
that
.
success
(
result
);
return
that
.
removeAttachment
(
command
);
}
}
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{
"
revision_needed
"
:
true
,
"
remove
"
:
true
},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
that
.
success
(
response
);
}
);
};
that
.
removeAttachment
=
function
(
command
)
{
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{
"
doc_id
"
:
command
.
getDocId
(),
"
attachment_id
"
:
command
.
getAttachmentId
(),
"
revision_needed
"
:
true
,
"
removeAttachment
"
:
true
,
"
remove_from_attachment_list
"
:
{
"
_attachment
"
:
command
.
getAttachmentId
()
}
},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
that
.
success
(
response
);
}
);
};
};
priv
.
send
(
"
allDocs
"
,
null
,
command
.
cloneOption
(),
function
(
err
,
response
)
{
var
i
,
j
,
row
,
selector
,
selected
;
that
.
get
=
function
(
command
)
{
if
(
err
)
{
if
(
command
.
getAttachmentId
()
)
{
return
that
.
error
(
err
);
return
that
.
getAttachment
(
command
);
}
}
selector
=
/
\.
revision_tree
\.
json$/
;
priv
.
revisionGenericRequest
(
rows
=
{
command
.
cloneDoc
(),
"
revision_trees
"
:
{
command
.
cloneOption
(),
// id.revision_tree.json: {
{
// id: blabla
"
get
"
:
true
// doc: {...}
// }
},
},
"
document_revisions
"
:
{
function
(
err
,
response
)
{
// id.rev: {
if
(
err
)
{
// id: blabla
return
that
.
error
(
err
);
// rev: 1-1
}
// doc: {...}
that
.
success
(
response
);
// }
}
}
);
};
that
.
getAttachment
=
function
(
command
)
{
priv
.
revisionGenericRequest
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
{
"
doc_id
"
:
command
.
getDocId
(),
"
attachment_id
"
:
command
.
getAttachmentId
(),
"
getAttachment
"
:
true
},
function
(
err
,
response
)
{
if
(
err
)
{
return
that
.
error
(
err
);
}
that
.
success
(
response
);
}
);
};
that
.
allDocs
=
function
(
command
)
{
var
rows
,
result
=
{
"
total_rows
"
:
0
,
"
rows
"
:
[]},
functions
=
{};
functions
.
finished
=
0
;
functions
.
falseResponseGenerator
=
function
(
response
,
callback
)
{
callback
(
undefined
,
response
);
};
};
while
(
response
.
rows
.
length
>
0
)
{
functions
.
fillResultGenerator
=
function
(
doc_id
)
{
// filling rows
return
function
(
err
,
doc_tree
)
{
row
=
response
.
rows
.
shift
();
var
document_revision
,
row
,
revs_info
;
selected
=
selector
.
exec
(
row
.
id
);
if
(
err
)
{
if
(
selected
)
{
return
that
.
error
(
err
);
selected
=
selected
.
input
.
substring
(
0
,
selected
.
index
);
// this is a revision tree
rows
.
revision_trees
[
row
.
id
]
=
{
"
id
"
:
selected
};
if
(
row
.
doc
)
{
rows
.
revision_trees
[
row
.
id
].
doc
=
row
.
doc
;
}
}
}
else
{
revs_info
=
priv
.
getWinnerRevsInfo
(
doc_tree
);
// this is a simple revision
document_revision
=
rows
.
document_revisions
[
row
.
id
]
=
{
rows
.
document_revisions
[
doc_id
+
"
.
"
+
revs_info
[
0
].
rev
];
"
id
"
:
row
.
id
.
split
(
"
.
"
).
slice
(
0
,
-
1
),
if
(
document_revision
)
{
"
rev
"
:
row
.
id
.
split
(
"
.
"
).
slice
(
-
1
)
row
=
{
};
"
id
"
:
doc_id
,
if
(
row
.
doc
)
{
"
key
"
:
doc_id
,
rows
.
document_revisions
[
row
.
id
].
doc
=
row
.
doc
;
"
value
"
:
{
"
rev
"
:
revs_info
[
0
].
rev
}
};
if
(
document_revision
.
doc
&&
command
.
getOption
(
"
include_docs
"
))
{
document_revision
.
doc
.
_id
=
doc_id
;
document_revision
.
doc
.
_rev
=
revs_info
[
0
].
rev
;
row
.
doc
=
document_revision
.
doc
;
}
result
.
rows
.
push
(
row
);
result
.
total_rows
+=
1
;
}
}
functions
.
success
();
};
};
functions
.
success
=
function
()
{
functions
.
finished
-=
1
;
if
(
functions
.
finished
===
0
)
{
that
.
success
(
result
);
}
}
}
};
functions
.
finished
+=
1
;
priv
.
send
(
"
allDocs
"
,
null
,
command
.
cloneOption
(
for
(
i
in
rows
.
revision_trees
)
{
),
function
(
err
,
response
)
{
if
(
rows
.
revision_trees
.
hasOwnProperty
(
i
))
{
var
i
,
j
,
row
,
selector
,
selected
;
functions
.
finished
+=
1
;
if
(
err
)
{
if
(
rows
.
revision_trees
[
i
].
doc
)
{
return
that
.
error
(
err
);
functions
.
falseResponseGenerator
(
}
rows
.
revision_trees
[
i
].
doc
,
selector
=
/
\.
revision_tree
\.
json$/
;
functions
.
fillResultGenerator
(
rows
.
revision_trees
[
i
].
id
)
rows
=
{
);
"
revision_trees
"
:
{
// id.revision_tree.json: {
// id: blabla
// doc: {...}
// }
},
"
document_revisions
"
:
{
// id.rev: {
// id: blabla
// rev: 1-1
// doc: {...}
// }
}
};
while
(
response
.
rows
.
length
>
0
)
{
// filling rows
row
=
response
.
rows
.
shift
();
selected
=
selector
.
exec
(
row
.
id
);
if
(
selected
)
{
selected
=
selected
.
input
.
substring
(
0
,
selected
.
index
);
// this is a revision tree
rows
.
revision_trees
[
row
.
id
]
=
{
"
id
"
:
selected
};
if
(
row
.
doc
)
{
rows
.
revision_trees
[
row
.
id
].
doc
=
row
.
doc
;
}
}
else
{
}
else
{
priv
.
getRevisionTree
(
// this is a simple revision
{
"
_id
"
:
rows
.
revision_trees
[
i
].
id
},
rows
.
document_revisions
[
row
.
id
]
=
{
command
.
cloneOption
(),
"
id
"
:
row
.
id
.
split
(
"
.
"
).
slice
(
0
,
-
1
),
functions
.
fillResultGenerator
(
rows
.
revision_trees
[
i
].
id
)
"
rev
"
:
row
.
id
.
split
(
"
.
"
).
slice
(
-
1
)
);
};
if
(
row
.
doc
)
{
rows
.
document_revisions
[
row
.
id
].
doc
=
row
.
doc
;
}
}
}
}
}
}
functions
.
finished
+=
1
;
functions
.
success
();
for
(
i
in
rows
.
revision_trees
)
{
});
if
(
rows
.
revision_trees
.
hasOwnProperty
(
i
))
{
};
functions
.
finished
+=
1
;
if
(
rows
.
revision_trees
[
i
].
doc
)
{
// END //
functions
.
falseResponseGenerator
(
priv
.
RevisionStorage
();
rows
.
revision_trees
[
i
].
doc
,
return
that
;
functions
.
fillResultGenerator
(
rows
.
revision_trees
[
i
].
id
)
});
// end RevisionStorage
);
}
else
{
priv
.
getRevisionTree
(
{
"
_id
"
:
rows
.
revision_trees
[
i
].
id
},
command
.
cloneOption
(),
functions
.
fillResultGenerator
(
rows
.
revision_trees
[
i
].
id
)
);
}
}
}
functions
.
success
();
});
};
// END //
priv
.
RevisionStorage
();
return
that
;
});
// end RevisionStorage
}));
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