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
Cédric Le Ninivin
jio
Commits
8e35d3a6
Commit
8e35d3a6
authored
Dec 24, 2012
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
JIO Basic Storage revision managing removed! Improving modularity!
parent
3fd058c3
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
7 additions
and
822 deletions
+7
-822
src/jio.storage/intro.js
src/jio.storage/intro.js
+0
-375
src/jio.storage/localstorage.js
src/jio.storage/localstorage.js
+1
-1
src/jio/commands/_allDocsCommand.js
src/jio/commands/_allDocsCommand.js
+0
-24
src/jio/commands/_getCommand.js
src/jio/commands/_getCommand.js
+0
-32
src/jio/commands/_postCommand.js
src/jio/commands/_postCommand.js
+0
-18
src/jio/commands/_putAttachmentCommand.js
src/jio/commands/_putAttachmentCommand.js
+0
-27
src/jio/commands/_putCommand.js
src/jio/commands/_putCommand.js
+0
-26
src/jio/commands/_removeCommand.js
src/jio/commands/_removeCommand.js
+0
-16
src/jio/commands/command.js
src/jio/commands/command.js
+0
-6
src/jio/commands/putCommand.js
src/jio/commands/putCommand.js
+0
-8
src/jio/storages/storage.js
src/jio/storages/storage.js
+6
-289
No files found.
src/jio.storage/intro.js
View file @
8e35d3a6
...
...
@@ -7,381 +7,6 @@
* - CryptedStorage ('crypted')
* - ConflictManagerStorage ('conflictmanager')
*
* @module cross-storage methods
*/
var
utilities
=
{
/**
* Generates a hash code of a string
* @method hashCode
* @param {string} string The string to hash
* @return {string} The string hash code
*/
hashCode
:
function
(
string
)
{
return
hex_sha256
(
string
);
},
/**
* 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 {string} string String to help generate hash code
* @return {array} 0:The next revision number and 1:the hash code
*/
generateNextRevision
:
function
(
previous_revision
,
string
)
{
return
[
parseInt
(
previous_revision
.
split
(
'
-
'
)[
0
],
10
)
+
1
,
utilities
.
hashCode
(
previous_revision
+
string
)];
},
/**
* Replace substrings to others substring following a [list_of_replacement].
* It will be executed recusively to replace substrings which are not
* replaced substrings.
* It starts from the last element of the list of replacement.
* @method replaceSubString
* @param {string} string The string to replace
* @param {array} list_of_replacement A list containing arrays with 2
* values:
* - {string} The substring to replace
* - {string} The new substring
* ex: [['b', 'abc'], ['abc', 'cba']]
* @return {string} The new string
*/
replaceSubString
:
function
(
string
,
list_of_replacement
)
{
var
i
,
split_string
=
string
.
split
(
list_of_replacement
[
0
][
0
]);
if
(
list_of_replacement
[
1
])
{
for
(
i
=
0
;
i
<
split_string
.
length
;
i
+=
1
)
{
split_string
[
i
]
=
utilities
.
replaceSubString
(
split_string
[
i
],
list_of_replacement
.
slice
(
1
)
);
}
}
return
split_string
.
join
(
list_of_replacement
[
0
][
1
]);
},
/**
* It secures the [string] replacing all '%' by '%%' and '/' by '%2F'.
* @method secureString
* @param {string} string The string to secure
* @return {string} The secured string
*/
secureString
:
function
(
string
)
{
return
utilities
.
replaceSubString
(
string
,
[[
'
/
'
,
'
%2F
'
],[
'
%
'
,
'
%%
'
]]);
},
/**
* It replaces all '%2F' by '/' and '%%' by '%'.
* @method unsecureString
* @param {string} string The string to convert
* @return {string} The converted string
*/
unsecureString
:
function
(
string
)
{
return
utilities
.
replaceSubString
(
string
,
[[
'
%%
'
,
'
%
'
],[
'
%2F
'
,
'
/
'
]]);
},
// ============================ CREATE/UPDATE DOCUMENT =====================
/**
* @method createDocument - Creates a new document
* @info - docid POST = "" for POST, PUT = string
* @param {docid} string - id for the new document
* @stored - 'jio/local/USR/APP/FILE_NAME'
* @returns {doc} object - document object
*/
createDocument
:
function
(
docId
)
{
var
now
=
Date
.
now
(),
doc
=
{},
hash
=
utilities
.
hashCode
(
''
+
doc
+
'
'
+
now
+
''
);
doc
.
_id
=
docId
;
doc
.
_rev
=
'
1-
'
+
hash
;
doc
.
_revisions
=
{
start
:
1
,
ids
:
[
hash
]
};
doc
.
_revs_info
=
[{
rev
:
'
1-
'
+
hash
,
status
:
'
available
'
}];
return
doc
;
},
/**
* @method updateDocument - updates a document
* @info - called from PUT or PUTATTACHMENT
* @info - deletes old document (purge & replace)
* @param {docid} string - id for the new document
* @param {docpath} string - the path where to store the document
* @param {previousRevision} string - the previous revision
* @param {attachmentId} - string - in case attachments are handled
* @returns {doc} object - new document
*/
updateDocument
:
function
(
doc
,
docPath
,
previousRevision
,
attachmentId
)
{
var
now
=
Date
.
now
(),
rev
=
utilities
.
generateNextRevision
(
previousRevision
,
''
+
doc
+
'
'
+
now
+
''
);
// in case the update is made because of an attachment
if
(
attachmentId
!==
undefined
)
{
// create _attachments
if
(
doc
.
_attachments
===
undefined
){
doc
.
_attachments
=
{};
}
// create _attachments object for this attachment
if
(
doc
.
_attachments
[
attachmentId
]
===
undefined
){
doc
.
_attachments
[
attachmentId
]
=
{};
}
// set revpos
doc
.
_attachments
[
attachmentId
].
revpos
=
parseInt
(
doc
.
_rev
.
split
(
'
-
'
)[
0
],
10
);
}
// update document
doc
.
_rev
=
rev
.
join
(
'
-
'
);
doc
.
_revisions
.
ids
.
unshift
(
rev
[
1
]);
doc
.
_revisions
.
start
=
rev
[
0
];
doc
.
_revs_info
[
0
].
status
=
'
deleted
'
;
doc
.
_revs_info
.
unshift
({
"
rev
"
:
rev
.
join
(
'
-
'
),
"
status
"
:
"
available
"
});
return
doc
;
},
/**
* @method updateDocumentTree- update a document tree
* @param {docTreeNode} object - document tree
* @param {old_rev} string - revision of the tree node to set to "branch"
* @param {new_rev } string - revison of the tree node to add as leaf
* @param {revs_info} object- history of new_rev to merge with remote tree
*/
updateDocumentTree
:
function
(
docTreeNode
,
old_rev
,
new_rev
,
revs_info
,
deletedLeaf
)
{
if
(
typeof
revs_info
===
"
object
"
)
{
// a new document version is being stored from another storage
utilities
.
mergeRemoteTree
(
docTreeNode
,
docTreeNode
,
old_rev
,
new_rev
,
revs_info
,
[],
false
,
deletedLeaf
);
}
else
{
// update an existing version of document = add a node to the tree
utilities
.
setTreeNode
(
docTreeNode
,
old_rev
,
new_rev
,
'
available
'
);
}
return
docTreeNode
;
},
// ==================== SET/MERGE/CHECK TREE NODES ==================
/**
* @method setTreeNode - adds a new tree node/changes leaf to branch
* @param {docTreeNode} object - document tree
* @param {old_rev} string - revision of the tree node to set to "branch"
* @param {new_rev } string - revison of the tree node to add as leaf
* @param {new_status}string- status the new node should have
* @info - status is necessary, because we may also
* add deleted nodes to the tree from a
* remote storage
*/
setTreeNode
:
function
(
docTreeNode
,
old_rev
,
new_rev
,
new_status
){
var
kids
=
docTreeNode
[
'
kids
'
],
rev
=
docTreeNode
[
'
rev
'
],
numberOfKids
,
i
,
key
;
for
(
key
in
docTreeNode
){
if
(
key
===
"
rev
"
){
// grow the tree
if
(
old_rev
===
rev
&&
new_rev
!==
rev
)
{
docTreeNode
.
type
=
'
branch
'
;
docTreeNode
.
status
=
'
deleted
'
;
docTreeNode
.
kids
.
push
({
type
:
'
leaf
'
,
status
:
new_status
,
rev
:
new_rev
,
kids
:[]
});
}
else
{
// traverse until correct node is found!
if
(
utilities
.
isObjectEmpty
(
kids
)
===
false
)
{
numberOfKids
=
utilities
.
isObjectSize
(
kids
);
for
(
i
=
0
;
i
<
numberOfKids
;
i
+=
1
){
utilities
.
setTreeNode
(
kids
[
i
],
old_rev
,
new_rev
,
new_status
);
}
}
}
}
}
return
docTreeNode
;
},
/**
* Merges document object trees
* @method mergeDocumentTree
* @param {object} document_tree_list The document tree array
*/
mergeDocumentTree
:
function
(
document_tree_list
)
{
var
arrayConcat
,
each
,
synchronizeFrom
,
tree_list
;
// arrayConcat([1,2], [3,4]) = [1,2,3,4]
arrayConcat
=
function
()
{
var
i
,
newlist
=
[];
for
(
j
=
0
;
j
<
arguments
.
length
;
++
j
)
{
for
(
i
=
0
;
i
<
arguments
[
j
].
length
;
++
i
)
{
newlist
.
push
(
arguments
[
j
][
i
]);
}
}
return
newlist
;
};
// "each" executes "fun" on each values of "array"
// if return false, then stop browsing
each
=
function
(
array
,
fun
,
start
)
{
var
i
;
for
(
i
=
start
||
0
;
i
<
array
.
length
;
i
+=
1
)
{
if
(
fun
(
array
[
i
],
i
)
===
false
)
{
return
false
;
}
}
return
true
;
};
// merges all trees
synchronize
=
function
(
tree_list
)
{
var
new_children
;
new_children
=
[];
each
(
tree_list
,
function
(
tree
,
tree_index
)
{
var
res
;
if
(
new_children
.
length
===
0
)
{
new_children
.
push
(
tree
);
return
;
}
res
=
each
(
new_children
,
function
(
child
,
child_index
)
{
if
(
tree
.
rev
===
child
.
rev
)
{
new_children
[
child_index
].
children
=
synchronize
(
arrayConcat
(
tree
.
children
,
child
.
children
)
)
return
false
;
}
});
if
(
res
===
true
)
{
new_children
.
push
(
tree
);
}
});
return
new_children
;
};
tree_list
=
[];
each
(
document_tree_list
,
function
(
tree
)
{
tree_list
=
arrayConcat
(
tree_list
,
tree
.
children
);
});
return
{
"
children
"
:
synchronize
(
tree_list
)};
},
/**
* 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 {string} The winner revision
*/
getWinnerRevisionFromDocumentTree
:
function
(
document_tree
)
{
var
i
,
result
,
search
;
result
=
{
"
deep
"
:
-
1
,
"
revision
"
:
''
};
// search method fills "result" with the winner revision
search
=
function
(
document_tree
,
deep
)
{
var
i
;
if
(
document_tree
.
children
.
length
===
0
)
{
// This node is a leaf
if
(
result
.
deep
<
deep
)
{
// The leaf is deeper than result
result
=
{
"
deep
"
:
deep
,
"
revision
"
:
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
],
deep
+
1
);
}
};
search
(
document_tree
,
0
);
return
result
.
rev
;
},
/**
* Gets an array of leaves revisions from document tree
* @method getLeavesFromDocumentTree
* @param {object} document_tree The document tree
* @return {array} The array of leaves revisions
*/
getLeavesFromDocumentTree
:
function
(
document_tree
)
{
var
i
,
result
,
search
;
result
=
[];
// search method fills [result] with the winner revision
search
=
function
(
document_tree
)
{
var
i
;
if
(
document_tree
.
children
.
length
===
0
)
{
// 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
;
},
/**
* @method isDeadLeaf - Check if revision is branch or status deleted
* @param {node} string - revision
* @param {tree} object - active leaves (versions of a document)
* @returns - true/false
*/
isDeadLeaf
:
function
(
prev_rev
,
docTreeNode
){
var
type
=
docTreeNode
[
'
type
'
],
status
=
docTreeNode
[
'
status
'
],
kids
=
docTreeNode
[
'
kids
'
],
rev
=
docTreeNode
[
'
rev
'
],
result
=
false
,
numberOfKids
,
i
,
key
;
for
(
key
in
docTreeNode
){
if
(
key
===
"
rev
"
){
// if prev_rev is found, check if deleted or branch
if
(
prev_rev
===
rev
&&
(
type
===
'
branch
'
||
status
===
'
deleted
'
)
){
result
=
true
;
}
if
(
utilities
.
isObjectEmpty
(
kids
)
===
false
){
numberOfKids
=
utilities
.
isObjectSize
(
kids
);
for
(
i
=
0
;
i
<
numberOfKids
;
i
+=
1
){
// recurse
if
(
utilities
.
isDeadLeaf
(
prev_rev
,
kids
[
i
]
)
===
true
){
result
=
true
;
}
}
}
return
result
;
}
}
}
};
/*
* @module JIOStorages
*/
(
function
(
LocalOrCookieStorage
,
$
,
Base64
,
sjcl
,
hex_sha256
,
jIO
)
{
src/jio.storage/localstorage.js
View file @
8e35d3a6
...
...
@@ -26,7 +26,7 @@ var newLocalStorage = function (spec, my) {
storage_user_array_name
,
storage_file_array_name
;
// attributes
// attributes
priv
.
username
=
spec
.
username
||
''
;
priv
.
applicationname
=
spec
.
applicationname
||
'
untitled
'
;
...
...
src/jio/commands/_allDocsCommand.js
deleted
100644 → 0
View file @
3fd058c3
var
_allDocsCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
_allDocs
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
_allDocs
(
that
);
};
that
.
canBeRestored
=
function
()
{
return
false
;
};
that
.
validateState
=
function
()
{
return
true
;
};
return
that
;
};
src/jio/commands/_getCommand.js
deleted
100644 → 0
View file @
3fd058c3
var
_getCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
_get
'
;
};
that
.
validateState
=
function
()
{
if
(
!
that
.
getDocId
())
{
that
.
error
({
status
:
20
,
statusText
:
'
Document Id Required
'
,
error
:
'
document_id_required
'
,
message
:
'
No document id.
'
,
reason
:
'
no document id
'
});
return
false
;
}
return
true
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
_get
(
that
);
};
that
.
canBeRestored
=
function
()
{
return
false
;
};
return
that
;
};
src/jio/commands/_postCommand.js
deleted
100644 → 0
View file @
3fd058c3
var
_postCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
var
priv
=
{};
// Methods //
that
.
getLabel
=
function
()
{
return
'
_post
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
_post
(
that
);
};
return
that
;
};
src/jio/commands/_putAttachmentCommand.js
deleted
100644 → 0
View file @
3fd058c3
var
_putAttachmentCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
_putAttachment
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
_putAttachment
(
that
);
};
that
.
validateState
=
function
()
{
if
(
typeof
that
.
getContent
()
!==
'
string
'
)
{
that
.
error
({
status
:
22
,
statusText
:
'
Content Required
'
,
error
:
'
content_required
'
,
message
:
'
No data to put.
'
,
reason
:
'
no data to put
'
});
return
false
;
}
return
true
;
};
return
that
;
};
src/jio/commands/_putCommand.js
deleted
100644 → 0
View file @
3fd058c3
var
_putCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
var
priv
=
{};
// Methods //
that
.
getLabel
=
function
()
{
return
'
_put
'
;
};
/**
* Validates the storage handler.
* @param {object} handler The storage handler
*/
that
.
validate
=
function
()
{
return
that
.
validateState
();
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
_put
(
that
);
};
return
that
;
};
src/jio/commands/_removeCommand.js
deleted
100644 → 0
View file @
3fd058c3
var
_removeCommand
=
function
(
spec
,
my
)
{
var
that
=
command
(
spec
,
my
);
spec
=
spec
||
{};
my
=
my
||
{};
// Attributes //
// Methods //
that
.
getLabel
=
function
()
{
return
'
_remove
'
;
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
_remove
(
that
);
};
return
that
;
};
src/jio/commands/command.js
View file @
8e35d3a6
...
...
@@ -11,12 +11,6 @@ var command = function(spec, my) {
'
remove
'
:
removeCommand
,
'
allDocs
'
:
allDocsCommand
,
'
putAttachment
'
:
putAttachmentCommand
'
_post
'
:
_postCommand
,
'
_put
'
:
_putCommand
,
'
_get
'
:
_getCommand
,
'
_remove
'
:
_removeCommand
,
'
_allDocs
'
:
_allDocsCommand
,
'
_putAttachment
'
:
_putAttachmentCommand
};
// creates the good command thanks to his label
if
(
spec
.
label
&&
priv
.
commandlist
[
spec
.
label
])
{
...
...
src/jio/commands/putCommand.js
View file @
8e35d3a6
...
...
@@ -10,14 +10,6 @@ var putCommand = function(spec, my) {
return
'
put
'
;
};
/**
* Validates the storage handler.
* @param {object} handler The storage handler
*/
that
.
validate
=
function
()
{
return
that
.
validateState
();
};
that
.
executeOn
=
function
(
storage
)
{
storage
.
put
(
that
);
};
...
...
src/jio/storages/storage.js
View file @
8e35d3a6
...
...
@@ -14,214 +14,6 @@ var storage = function(spec, my) {
}
});
/**
* Generate a new uuid
* @method generateUuid
* @return {string} The new uuid
*/
that
.
generateUuid
=
function
()
{
var
S4
=
function
()
{
var
i
,
string
=
Math
.
floor
(
Math
.
random
()
*
0x10000
/* 65536 */
).
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
*/
that
.
hashCode
=
function
(
string
)
{
return
hex_sha256
(
string
);
};
/**
* Returns an array version of a revision string
* @method revisionToArray
* @param {string} revision The revision string
* @return {array} Array containing a revision number and a hash
*/
that
.
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 {string} string String to help generate hash code
* @return {array} 0:The next revision number and 1:the hash code
*/
that
.
generateNextRevision
=
function
(
previous_revision
,
string
)
{
if
(
typeof
previous_revision
===
"
number
"
)
{
return
[
previous_revision
+
1
,
that
.
hashCode
(
string
)];
}
previous_revision
=
that
.
revisionToArray
(
previous_revision
);
return
[
previous_revision
[
0
]
+
1
,
that
.
hashCode
(
string
)];
};
/**
* Checks a revision format
* @method checkRevisionFormat
* @param {string} revision The revision string
* @return {boolean} True if ok, else false
*/
that
.
checkRevisionFormat
=
function
(
revision
)
{
return
/^
[
0-9
]
+-
[
0-9a-zA-Z
]
+$/
.
test
(
revision
);
};
/**
* Creates the error object for all errors
* @method createErrorObject
* @param {number} error_code The error code
* @param {string} error_name The error name
* @param {string} message The error message
* @param {object} error_object The error object (optional)
* @return {object} Error object
*/
that
.
createErrorObject
=
function
(
error_code
,
error_name
,
message
,
error_object
)
{
error_object
=
error_object
||
{};
error_okject
[
"
status
"
]
=
error_code
||
0
;
error_object
[
"
statusText
"
]
=
error_name
;
error_object
[
"
error
"
]
=
error_name
.
toLowerCase
().
split
(
'
'
).
join
(
'
_
'
);
error_object
[
"
message
"
]
=
error_object
[
"
error
"
]
=
message
;
return
error_object
;
};
/**
* Creates an empty document tree
* @method createDocumentTree
* @param {array} children An array of children (optional)
* @return {object} The new document tree
*/
that
.
createDocumentTree
=
function
(
children
)
{
return
{
"
children
"
:
children
||
[]};
};
/**
* Creates a new document tree node
* @method createDocumentTreeNode
* @param {string} revision The node revision
* @param {string} status The node status
* @param {array} children An array of children (optional)
* @return {object} The new document tree node
*/
that
.
createDocumentTreeNode
=
function
(
revision
,
status
,
children
)
{
return
{
"
rev
"
:
revision
,
"
status
"
:
status
,
"
children
"
:
children
||
[]};
};
/**
* Gets the winner revision from a document tree.
* The winner is the deeper revision on the left.
* @method getWinnerRevisionFromDocumentTree
* @param {object} document_tree The document tree
* @return {string} The winner revision
*/
that
.
getWinnerRevisionFromDocumentTree
=
function
(
document_tree
)
{
var
i
,
result
,
search
;
result
=
{
"
deep
"
:
-
1
,
"
revision
"
:
''
};
// search method fills "result" with the winner revision
search
=
function
(
document_tree
,
deep
)
{
var
i
;
if
(
document_tree
.
children
.
length
===
0
)
{
// This node is a leaf
if
(
result
.
deep
<
deep
)
{
// The leaf is deeper than result
result
=
{
"
deep
"
:
deep
,
"
revision
"
:
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
],
deep
+
1
);
}
};
search
(
document_tree
,
0
);
return
result
.
rev
;
};
/**
* Gets an array of leaves revisions from document tree
* @method getLeavesFromDocumentTree
* @param {object} document_tree The document tree
* @return {array} The array of leaves revisions
*/
that
.
getLeavesFromDocumentTree
=
function
(
document_tree
)
{
var
i
,
result
,
search
;
result
=
[];
// search method fills [result] with the winner revision
search
=
function
(
document_tree
)
{
var
i
;
if
(
document_tree
.
children
.
length
===
0
)
{
// 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
;
};
that
.
createDocument
=
function
(
doc
,
id
,
prev_rev
)
{
var
hash
,
rev
;
if
(
typeof
prev_rev
===
"
undefined
"
)
{
hash
=
that
.
hashCode
(
doc
);
doc
.
_rev
=
"
1-
"
+
hash
;
doc
.
_id
=
id
;
doc
.
_revisions
=
{
"
start
"
:
1
,
"
ids
"
:
[
hash
]
};
doc
.
_revs_info
=
[{
"
rev
"
:
"
1-
"
+
hash
,
"
status
"
:
"
available
"
}];
return
doc
;
}
else
{
// xxx do not hash _key of doc!
prev_rev
=
that
.
revisionToArray
(
prev_rev
);
rev
=
that
.
generateNextRevision
(
prev_rev
,
doc
);
doc
.
_rev
=
rev
.
join
(
'
-
'
);
doc
.
_id
=
id
;
doc
.
_revisions
=
{
"
start
"
:
rev
[
0
],
"
ids
"
:
[
rev
[
1
],
prev_rev
[
1
]]
};
doc
.
_revs_info
=
[{
"
rev
"
:
rev
.
join
(
'
-
'
),
"
status
"
:
"
available
"
},{
"
rev
"
:
prev_rev
.
join
(
'
-
'
),
"
status
"
:
"
missing
"
}];
return
doc
;
}
};
/**
* Execute the command on this storage.
* @method execute
...
...
@@ -289,82 +81,7 @@ var storage = function(spec, my) {
return
''
;
};
that
.
post
=
function
(
command
)
{
setTimeout
(
function
()
{
var
f
,
options
,
document_tree
,
doc
,
prev_rev
;
f
=
{};
options
=
command
.
cloneOption
();
options
[
"
max_retry
"
]
=
options
[
"
max_retry
"
]
||
3
;
f
.
begin
=
function
()
{
prev_rev
=
command
.
getDocInfo
(
"
_rev
"
);
if
(
typeof
prev_rev
===
"
string
"
&&
!
that
.
checkRevisionFormat
(
prev_rev
))
{
// if the previous revision given is bad
that
.
error
(
that
.
createErrorObject
(
400
,
"
Bad Request
"
,
"
Invalid rev format
"
));
return
;
}
doc
=
that
.
createDocument
(
command
.
getDoc
()
||
{},
command
.
getDocId
()
||
that
.
generateUuid
(),
prev_rev
);
// the previous revision is correct
prev_rev
=
that
.
revisionToArray
(
prev_rev
);
f
.
getDocumentTree
();
};
// check if the tree already exists
f
.
getDocumentTree
=
function
()
{
that
.
addJob
(
'
_get
'
,
that
.
serialized
(),
doc
.
_id
+
'
.tree.json
'
,
options
,
function
(
response
)
{
// if the tree exists
document_tree
=
response
;
f
.
postDocument
();
},
function
(
error
)
{
if
(
error
.
status
===
404
)
{
// if the tree does not exists yet
document_tree
=
that
.
createDocumentTree
();
f
.
postDocument
();
}
else
{
that
.
error
(
that
.
createErrorObject
(
error
.
status
,
error
.
statusText
,
"
Unable to get the revision tree
"
));
}
}
);
};
f
.
postDocument
=
function
()
{
that
.
addJob
(
'
_post
'
,
that
.
serialized
(),
doc
.
_id
+
'
.
'
+
doc
.
_rev
,
options
,
function
(
response
)
{
f
.
putDocumentTree
()
},
function
(
error
)
{
that
.
error
(
that
.
createErrorObject
(
error
.
status
,
error
.
statusText
,
error
));
}
);
};
f
.
putDocumentTree
=
function
()
{
if
(
!
that
.
addDocumentToDocumentTree
(
doc
))
{
// conflict!
}
// xxx
};
f
.
begin
();
});
};
that
.
_post
=
function
()
{
that
.
post
=
function
()
{
setTimeout
(
function
()
{
that
.
error
(
that
.
createErrorObject
(
0
,
"
Not Implemented Yet
"
,
"
\"
Post
\"
command is not implemented
"
...
...
@@ -372,7 +89,7 @@ var storage = function(spec, my) {
});
};
that
.
_
put
=
function
()
{
that
.
put
=
function
()
{
setTimeout
(
function
()
{
that
.
error
(
that
.
createErrorObject
(
0
,
"
Not Implemented Yet
"
,
"
\"
Put
\"
command is not implemented
"
...
...
@@ -380,7 +97,7 @@ var storage = function(spec, my) {
});
};
that
.
_
putAttachment
=
function
()
{
that
.
putAttachment
=
function
()
{
setTimeout
(
function
()
{
that
.
error
(
that
.
createErrorObject
(
0
,
"
Not Implemented Yet
"
,
...
...
@@ -389,7 +106,7 @@ var storage = function(spec, my) {
});
};
that
.
_
get
=
function
()
{
that
.
get
=
function
()
{
setTimeout
(
function
()
{
that
.
error
(
that
.
createErrorObject
(
0
,
"
Not Implemented Yet
"
,
"
\"
Get
\"
command is not implemented
"
...
...
@@ -397,7 +114,7 @@ var storage = function(spec, my) {
});
};
that
.
_
allDocs
=
function
()
{
that
.
allDocs
=
function
()
{
setTimeout
(
function
()
{
that
.
error
(
that
.
createErrorObject
(
0
,
"
Not Implemented Yet
"
,
...
...
@@ -406,7 +123,7 @@ var storage = function(spec, my) {
});
};
that
.
_
remove
=
function
()
{
that
.
remove
=
function
()
{
setTimeout
(
function
()
{
that
.
error
(
that
.
createErrorObject
(
0
,
"
Not Implemented Yet
"
,
...
...
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