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
Junming
jio
Commits
3cfc4665
Commit
3cfc4665
authored
Jul 08, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'splitstorage'
parents
9d099782
bf4d0443
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1104 additions
and
0 deletions
+1104
-0
examples/jio_dashboard.html
examples/jio_dashboard.html
+2
-0
src/jio.storage/splitstorage.js
src/jio.storage/splitstorage.js
+613
-0
test/jiotests.js
test/jiotests.js
+487
-0
test/jiotests_withoutrequirejs.html
test/jiotests_withoutrequirejs.html
+2
-0
No files found.
examples/jio_dashboard.html
View file @
3cfc4665
...
...
@@ -162,6 +162,8 @@ var clearlog = function () {
<script
type=
"text/javascript"
src=
"../lib/jsSha2/sha2.js"
></script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/revisionstorage.js"
>
</script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/splitstorage.js"
>
</script>
<script
type=
"text/javascript"
src=
"../lib/sjcl/sjcl.min.js"
></script>
<script
type=
"text/javascript"
>
<!--
...
...
src/jio.storage/splitstorage.js
0 → 100644
View file @
3cfc4665
/*
* Copyright 2013, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/*jslint indent:2, maxlen: 80, nomen: true */
/*global jIO: true, exports: true, define: true */
/**
* Provides a split storage for JIO. This storage splits data
* and store them in the sub storages defined on the description.
*
* {
* "type": "split",
* "storage_list": [<storage description>, ...]
* }
*/
(
function
()
{
"
use strict
"
;
var
queries
;
/**
* Get the real type of an object
*
* @param {Any} value The value to check
* @return {String} The value type
*/
function
type
(
value
)
{
// returns "String", "Object", "Array", "RegExp", ...
return
(
/^
\[
object
([
a-zA-Z
]
+
)\]
$/
).
exec
(
Object
.
prototype
.
toString
.
call
(
value
)
)[
1
];
}
/**
* Generate a new uuid
*
* @method generateUuid
* @private
* @return {String} The new uuid
*/
function
generateUuid
()
{
function
S4
()
{
/* 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
();
}
/**
* Class to merge allDocs responses from several sub storages.
*
* @class AllDocsResponseMerger
* @constructor
*/
function
AllDocsResponseMerger
()
{
/**
* A list of allDocs response.
*
* @attribute response_list
* @type {Array} Contains allDocs responses
* @default []
*/
this
.
response_list
=
[];
}
AllDocsResponseMerger
.
prototype
.
constructor
=
AllDocsResponseMerger
;
/**
* Add an allDocs response to the response list.
*
* @method addResponse
* @param {Object} response The allDocs response.
* @return {AllDocsResponseMerger} This
*/
AllDocsResponseMerger
.
prototype
.
addResponse
=
function
(
response
)
{
this
.
response_list
.
push
(
response
);
return
this
;
};
/**
* Add several allDocs responses to the response list.
*
* @method addResponseList
* @param {Array} response_list An array of allDocs responses.
* @return {AllDocsResponseMerger} This
*/
AllDocsResponseMerger
.
prototype
.
addResponseList
=
function
(
response_list
)
{
var
i
;
for
(
i
=
0
;
i
<
response_list
.
length
;
i
+=
1
)
{
this
.
response_list
.
push
(
response_list
[
i
]);
}
return
this
;
};
/**
* Merge the response_list to one allDocs response.
*
* The merger will find rows with the same id in order to merge them, thanks
* to the onRowToMerge method. If no row correspond to an id, rows with the
* same id will be ignored.
*
* @method merge
* @param {Object} [option={}] The merge options
* @param {Boolean} [option.include_docs=false] Tell the merger to also
* merge metadata if true.
* @return {Object} The merged allDocs response.
*/
AllDocsResponseMerger
.
prototype
.
merge
=
function
(
option
)
{
var
result
=
[],
row
,
to_merge
=
[],
tmp
,
i
;
if
(
this
.
response_list
.
length
===
0
)
{
return
[];
}
while
((
row
=
this
.
response_list
[
0
].
rows
.
shift
())
!==
undefined
)
{
console
.
log
(
'
row
'
,
row
);
to_merge
[
0
]
=
row
;
for
(
i
=
1
;
i
<
this
.
response_list
.
length
;
i
+=
1
)
{
to_merge
[
i
]
=
AllDocsResponseMerger
.
listPopFromRowId
(
this
.
response_list
[
i
].
rows
,
row
.
id
);
if
(
to_merge
[
i
]
===
undefined
)
{
break
;
}
}
console
.
log
(
'
to merge
'
,
to_merge
);
tmp
=
this
.
onRowToMerge
(
to_merge
,
option
||
{});
if
(
tmp
!==
undefined
)
{
result
[
result
.
length
]
=
tmp
;
}
}
this
.
response_list
=
[];
return
{
"
total_rows
"
:
result
.
length
,
"
rows
"
:
result
};
};
/**
* This method is called when the merger want to merge several rows with the
* same id.
*
* @method onRowToMerge
* @param {Array} row_list An array of rows.
* @param {Object} [option={}] The merge option.
* @param {Boolean} [option.include_docs=false] Also merge the metadata if
* true
* @return {Object} The merged row
*/
AllDocsResponseMerger
.
prototype
.
onRowToMerge
=
function
(
row_list
,
option
)
{
var
i
,
k
,
new_row
=
{
"
value
"
:
{}},
data
=
""
;
option
=
option
||
{};
for
(
i
=
0
;
i
<
row_list
.
length
;
i
+=
1
)
{
new_row
.
id
=
row_list
[
i
].
id
;
if
(
row_list
[
i
].
key
)
{
new_row
.
key
=
row_list
[
i
].
key
;
}
if
(
option
.
include_docs
)
{
new_row
.
doc
=
new_row
.
doc
||
{};
for
(
k
in
row_list
[
i
].
doc
)
{
if
(
row_list
[
i
].
doc
.
hasOwnProperty
(
k
))
{
if
(
k
[
0
]
===
"
_
"
)
{
new_row
.
doc
[
k
]
=
row_list
[
i
].
doc
[
k
];
}
}
}
data
+=
row_list
[
i
].
doc
.
data
;
}
}
if
(
option
.
include_docs
)
{
try
{
data
=
JSON
.
parse
(
data
);
}
catch
(
e
)
{
return
undefined
;
}
for
(
k
in
data
)
{
if
(
data
.
hasOwnProperty
(
k
))
{
new_row
.
doc
[
k
]
=
data
[
k
];
}
}
}
return
new_row
;
};
/**
* Search for a specific row and pop it. During the search operation, all
* parsed rows are stored on a dictionnary in order to be found instantly
* later.
*
* @method listPopFromRowId
* @param {Array} rows The row list
* @param {String} doc_id The document/row id
* @return {Object/undefined} The poped row
*/
AllDocsResponseMerger
.
listPopFromRowId
=
function
(
rows
,
doc_id
)
{
var
row
;
if
(
!
rows
.
dict
)
{
rows
.
dict
=
{};
}
if
(
rows
.
dict
[
doc_id
])
{
row
=
rows
.
dict
[
doc_id
];
delete
rows
.
dict
[
doc_id
];
return
row
;
}
while
((
row
=
rows
.
shift
())
!==
undefined
)
{
if
(
row
.
id
===
doc_id
)
{
return
row
;
}
rows
.
dict
[
row
.
id
]
=
row
;
}
};
/**
* The split storage class used by JIO.
*
* A split storage instance is able to i/o on several sub storages with
* split documents.
*
* @class splitStorage
*/
function
splitStorage
(
spec
,
my
)
{
var
that
=
my
.
basicStorage
(
spec
,
my
),
priv
=
{};
/**
* The list of sub storages we want to use to store part of documents.
*
* @attribute storage_list
* @private
* @type {Array} Array of storage descriptions
*/
priv
.
storage_list
=
spec
.
storage_list
;
//////////////////////////////////////////////////////////////////////
// Overrides
/**
* Overrides the original {{#crossLink "storage/specToStore:method"}}
* specToStore method{{/crossLink}}.
*
* @method specToStore
* @return {Object} The specificities to store
*/
that
.
specToStore
=
function
()
{
return
{
"
storage_list
"
:
priv
.
storage_list
};
};
/**
* TODO validateState
*/
//////////////////////////////////////////////////////////////////////
// Tools
/**
* Send a command to all sub storages. All the response are returned
* in a list. The index of the response correspond to the storage_list
* index. If an error occurs during operation, the callback is called with
* `callback(err, undefined)`. The response is given with
* `callback(undefined, response_list)`.
*
* `doc` is the document informations but can also be a list of dedicated
* document informations. In this case, each document is associated to one
* sub storage.
*
* @method send
* @private
* @param {String} method The command method
* @param {Object,Array} doc The document information to send to each sub
* storages or a list of dedicated document
* @param {Object} option The command option
* @param {Function} callback Called at the end
*/
priv
.
send
=
function
(
method
,
doc
,
option
,
callback
)
{
var
i
,
answer_list
=
[],
failed
=
false
;
function
onEnd
()
{
i
+=
1
;
if
(
i
===
priv
.
storage_list
.
length
)
{
callback
(
undefined
,
answer_list
);
}
}
function
onSuccess
(
i
)
{
return
function
(
response
)
{
if
(
!
failed
)
{
answer_list
[
i
]
=
response
;
}
onEnd
();
};
}
function
onError
(
i
)
{
return
function
(
err
)
{
if
(
!
failed
)
{
failed
=
true
;
err
.
index
=
i
;
callback
(
err
,
undefined
);
}
};
}
if
(
type
(
doc
)
!==
"
Array
"
)
{
for
(
i
=
0
;
i
<
priv
.
storage_list
.
length
;
i
+=
1
)
{
that
.
addJob
(
method
,
priv
.
storage_list
[
i
],
doc
,
option
,
onSuccess
(
i
),
onError
(
i
)
);
}
}
else
{
for
(
i
=
0
;
i
<
priv
.
storage_list
.
length
;
i
+=
1
)
{
that
.
addJob
(
method
,
priv
.
storage_list
[
i
],
doc
[
i
],
option
,
onSuccess
(
i
),
onError
(
i
)
);
}
}
i
=
0
;
};
/**
* Split document metadata then store them to the sub storages.
*
* @method postOrPut
* @private
* @param {Object} doc A serialized document object
* @param {Object} option Command option properties
* @param {String} method The command method ('post' or 'put')
*/
priv
.
postOrPut
=
function
(
doc
,
option
,
method
)
{
var
i
,
data
,
doc_list
=
[],
doc_underscores
=
{};
if
(
!
doc
.
_id
)
{
doc
.
_id
=
generateUuid
();
}
for
(
i
in
doc
)
{
if
(
doc
.
hasOwnProperty
(
i
))
{
if
(
i
[
0
]
===
"
_
"
)
{
doc_underscores
[
i
]
=
doc
[
i
];
delete
doc
[
i
];
}
}
}
data
=
JSON
.
stringify
(
doc
);
for
(
i
=
0
;
i
<
priv
.
storage_list
.
length
;
i
+=
1
)
{
doc_list
[
i
]
=
JSON
.
parse
(
JSON
.
stringify
(
doc_underscores
));
doc_list
[
i
].
data
=
data
.
slice
(
(
data
.
length
/
priv
.
storage_list
.
length
)
*
i
,
(
data
.
length
/
priv
.
storage_list
.
length
)
*
(
i
+
1
)
);
}
priv
.
send
(
method
,
doc_list
,
option
,
function
(
err
,
response
)
{
if
(
err
)
{
err
.
message
=
"
Unable to
"
+
method
+
"
document
"
;
delete
err
.
index
;
return
that
.
error
(
err
);
}
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
doc_underscores
.
_id
});
});
};
//////////////////////////////////////////////////////////////////////
// JIO commands
/**
* Split document metadata then store them to the sub storages.
*
* @method post
* @param {Command} command The JIO command
*/
that
.
post
=
function
(
command
)
{
priv
.
postOrPut
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
'
post
'
);
};
/**
* Split document metadata then store them to the sub storages.
*
* @method put
* @param {Command} command The JIO command
*/
that
.
put
=
function
(
command
)
{
priv
.
postOrPut
(
command
.
cloneDoc
(),
command
.
cloneOption
(),
'
put
'
);
};
/**
* Puts an attachment to the sub storages.
*
* @method putAttachment
* @param {Command} command The JIO command
*/
that
.
putAttachment
=
function
(
command
)
{
var
i
,
attachment_list
=
[],
data
=
command
.
getAttachmentData
();
for
(
i
=
0
;
i
<
priv
.
storage_list
.
length
;
i
+=
1
)
{
attachment_list
[
i
]
=
command
.
cloneDoc
();
attachment_list
[
i
].
_data
=
data
.
slice
(
(
data
.
length
/
priv
.
storage_list
.
length
)
*
i
,
(
data
.
length
/
priv
.
storage_list
.
length
)
*
(
i
+
1
)
);
}
priv
.
send
(
'
putAttachment
'
,
attachment_list
,
command
.
cloneOption
(),
function
(
err
,
response
)
{
if
(
err
)
{
err
.
message
=
"
Unable to put attachment
"
;
delete
err
.
index
;
return
that
.
error
(
err
);
}
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
(),
"
attachment
"
:
command
.
getAttachmentId
()
});
}
);
};
/**
* Gets splited document metadata then returns real document.
*
* @method get
* @param {Command} command The JIO command
*/
that
.
get
=
function
(
command
)
{
var
doc
,
option
,
data
,
attachments
;
doc
=
command
.
cloneDoc
();
option
=
command
.
cloneOption
();
priv
.
send
(
'
get
'
,
doc
,
option
,
function
(
err
,
response
)
{
var
i
,
k
;
if
(
err
)
{
err
.
message
=
"
Unable to get document
"
;
delete
err
.
index
;
return
that
.
error
(
err
);
}
doc
=
''
;
for
(
i
=
0
;
i
<
response
.
length
;
i
+=
1
)
{
doc
+=
response
[
i
].
data
;
}
doc
=
JSON
.
parse
(
doc
);
for
(
i
=
0
;
i
<
response
.
length
;
i
+=
1
)
{
for
(
k
in
response
[
i
])
{
if
(
response
[
i
].
hasOwnProperty
(
k
))
{
if
(
k
[
0
]
===
"
_
"
)
{
doc
[
k
]
=
response
[
i
][
k
];
}
}
}
}
delete
doc
.
_attachments
;
for
(
i
=
0
;
i
<
response
.
length
;
i
+=
1
)
{
if
(
response
[
i
].
_attachments
)
{
for
(
k
in
response
[
i
].
_attachments
)
{
if
(
response
[
i
].
_attachments
.
hasOwnProperty
(
k
))
{
doc
.
_attachments
=
doc
.
_attachments
||
{};
doc
.
_attachments
[
k
]
=
doc
.
_attachments
[
k
]
||
{
"
length
"
:
0
,
"
content_type
"
:
""
};
doc
.
_attachments
[
k
].
length
+=
response
[
i
].
_attachments
[
k
].
length
;
// if (response[i]._attachments[k].digest) {
// if (doc._attachments[k].digest) {
// doc._attachments[k].digest += " " + response[i].
// _attachments[k].digest;
// } else {
// doc._attachments[k].digest = response[i].
// _attachments[k].digest;
// }
// }
doc
.
_attachments
[
k
].
content_type
=
response
[
i
].
_attachments
[
k
].
content_type
;
}
}
}
}
doc
.
_id
=
command
.
getDocId
();
that
.
success
(
doc
);
});
};
/**
* Gets splited document attachment then returns real attachment data.
*
* @method getAttachment
* @param {Command} command The JIO command
*/
that
.
getAttachment
=
function
(
command
)
{
var
doc
,
option
;
doc
=
command
.
cloneDoc
();
option
=
command
.
cloneOption
();
priv
.
send
(
'
getAttachment
'
,
doc
,
option
,
function
(
err
,
response
)
{
var
i
,
k
;
if
(
err
)
{
err
.
message
=
"
Unable to get attachment
"
;
delete
err
.
index
;
return
that
.
error
(
err
);
}
doc
=
''
;
for
(
i
=
0
;
i
<
response
.
length
;
i
+=
1
)
{
doc
+=
response
[
i
];
}
that
.
success
(
doc
);
});
};
/**
* Removes a document from the sub storages.
*
* @method remove
* @param {Command} command The JIO command
*/
that
.
remove
=
function
(
command
)
{
priv
.
send
(
'
remove
'
,
command
.
cloneDoc
(),
command
.
cloneOption
(),
function
(
err
,
response_list
)
{
if
(
err
)
{
err
.
message
=
"
Unable to remove document
"
;
delete
err
.
index
;
return
that
.
error
(
err
);
}
that
.
success
({
"
id
"
:
command
.
getDocId
(),
"
ok
"
:
true
});
}
);
};
/**
* Removes an attachment from the sub storages.
*
* @method removeAttachment
* @param {Command} command The JIO command
*/
that
.
removeAttachment
=
function
(
command
)
{
var
doc
=
command
.
cloneDoc
();
priv
.
send
(
'
removeAttachment
'
,
doc
,
command
.
cloneOption
(),
function
(
err
,
response_list
)
{
if
(
err
)
{
err
.
message
=
"
Unable to remove attachment
"
;
delete
err
.
index
;
return
that
.
error
(
err
);
}
that
.
success
({
"
id
"
:
doc
.
_id
,
"
attachment
"
:
doc
.
_attachment
,
"
ok
"
:
true
});
}
);
};
/**
* Retreive a list of all document in the sub storages.
*
* If include_docs option is false, then it returns the document list from
* the first sub storage. Else, it will merge results and return.
*
* @method allDocs
* @param {Command} command The JIO command
*/
that
.
allDocs
=
function
(
command
)
{
var
option
=
command
.
cloneOption
();
option
=
{
"
include_docs
"
:
option
.
include_docs
};
priv
.
send
(
'
allDocs
'
,
command
.
cloneDoc
(),
option
,
function
(
err
,
response_list
)
{
var
all_docs_merger
;
if
(
err
)
{
err
.
message
=
"
Unable to retrieve document list
"
;
delete
err
.
index
;
return
that
.
error
(
err
);
}
all_docs_merger
=
new
AllDocsResponseMerger
();
all_docs_merger
.
addResponseList
(
response_list
);
return
that
.
success
(
all_docs_merger
.
merge
(
option
));
}
);
};
return
that
;
}
// end of splitStorage
//////////////////////////////
// exports to JIO
if
(
typeof
define
===
"
function
"
&&
define
.
amd
)
{
define
([
'
jio
'
],
function
(
jio
)
{
try
{
queries
=
require
(
'
complex_queries
'
);
}
catch
(
e
)
{}
jio
.
addStorageType
(
'
split
'
,
splitStorage
);
});
}
else
if
(
typeof
require
===
"
function
"
)
{
require
(
'
jio
'
).
addStorageType
(
'
split
'
,
splitStorage
);
}
else
if
(
typeof
jIO
===
"
object
"
)
{
jIO
.
addStorageType
(
'
split
'
,
splitStorage
);
}
else
{
throw
new
Error
(
"
Unable to export splitStorage to JIO.
"
);
}
}());
test/jiotests.js
View file @
3cfc4665
...
...
@@ -7347,6 +7347,493 @@ test ("XWiki Live Server setup", function () {
})();
// xwiki
module
(
"
SplitStorage + LocalStorage
"
);
test
(
"
Post
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
post1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
post2
"
}]
});
// post without id
o
.
spy
(
o
,
"
jobstatus
"
,
"
done
"
,
"
Post document without id
"
);
o
.
jio
.
post
({
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
},
function
(
err
,
response
)
{
o
.
f
(
err
,
response
);
o
.
uuid
=
(
err
||
response
).
id
;
ok
(
isUuid
(
o
.
uuid
),
"
Uuid should look like
"
+
"
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx :
"
+
o
.
uuid
);
});
o
.
tick
(
o
);
// check uploaded documents
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/post1/
'
+
o
.
uuid
),
{
"
_id
"
:
o
.
uuid
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
data
"
:
"
{
\"
meta
\"
"
},
"
Check uploaded document in sub storage 1
"
);
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/post2/
'
+
o
.
uuid
),
{
"
_id
"
:
o
.
uuid
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
data
"
:
"
:
\"
data
\"
}
"
},
"
Check uploaded document in sub storage 2
"
);
// post with id
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
one
"
},
"
Post document with id
"
);
o
.
jio
.
post
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
,
"
hello
"
:
"
world
"
},
o
.
f
);
o
.
tick
(
o
);
// check uploaded documents
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/post1/one
'
),
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
data
"
:
"
{
\"
meta
\"
:
\"
data
\"
,
"
},
"
Check uploaded document in sub storage 1
"
);
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/post2/one
'
),
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
data
"
:
"
\"
hello
\"
:
\"
world
\"
}
"
},
"
Check uploaded document in sub storage 2
"
);
// post with id
o
.
spy
(
o
,
"
status
"
,
409
,
"
Post document with same id
"
);
o
.
jio
.
post
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
,
"
hello
"
:
"
world
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
test
(
"
PutAttachment
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
putAttachment1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
putAttachment2
"
}]
});
o
.
spy
(
o
,
"
status
"
,
404
,
"
Put attachment on a inexistent document
"
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
,
"
_data
"
:
"
My Data
"
,
"
_mimetype
"
:
"
text/plain
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
post
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
one
"
,
"
attachment
"
:
"
my_attachment
"
},
"
Put attachment
"
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
,
"
_data
"
:
"
My Data
"
,
"
_mimetype
"
:
"
text/plain
"
},
o
.
f
);
o
.
tick
(
o
);
// check uploaded documents
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/putAttachment1/one
'
),
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
data
"
:
"
{
\"
meta
\"
"
,
"
_attachments
"
:
{
"
my_attachment
"
:
{
"
length
"
:
3
,
"
digest
"
:
"
md5-1b4686bc8ca15befdccb1da1dcb8c271
"
,
// md5("My ")
"
content_type
"
:
"
text/plain
"
}
}
},
"
Check uploaded document in sub storage 1
"
);
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/putAttachment2/one
'
),
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
data
"
:
"
:
\"
data
\"
}
"
,
"
_attachments
"
:
{
"
my_attachment
"
:
{
"
length
"
:
4
,
"
digest
"
:
"
md5-f6068daa29dbb05a7ead1e3b5a48bbee
"
,
// md5("Data")
"
content_type
"
:
"
text/plain
"
}
}
},
"
Check uploaded document in sub storage 2
"
);
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/putAttachment1/one/my_attachment
'
),
"
My
"
,
"
Check uploaded document in sub storage 1
"
);
deepEqual
(
localstorage
.
getItem
(
'
jio/localstorage/splitstorage/putAttachment2/one/my_attachment
'
),
"
Data
"
,
"
Check uploaded document in sub storage 2
"
);
o
.
jio
.
stop
();
});
test
(
"
Get
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
get1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
get2
"
}]
});
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get missing document
"
);
o
.
jio
.
get
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
post
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
},
"
Get posted document
"
);
o
.
jio
.
get
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
,
"
_data
"
:
"
My Data
"
,
"
_mimetype
"
:
"
text/plain
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
,
"
_attachments
"
:
{
"
my_attachment
"
:
{
"
length
"
:
7
,
"
content_type
"
:
"
text/plain
"
}
}
},
"
Get document with attachment informations
"
);
o
.
jio
.
get
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
test
(
"
GetAttachment
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
getAttachment1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
getAttachment2
"
}]
});
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get attachment from missing document
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
post
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get missing attachment from document
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
,
"
_data
"
:
"
My Data
"
,
"
_mimetype
"
:
"
text/plain
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
value
"
,
"
My Data
"
,
"
Get attachment
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
test
(
"
removeAttachment
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
removeAttachment1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
removeAttachment2
"
}]
});
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove attachment from inexistent document
"
);
o
.
jio
.
removeAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
post
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove inexistent attachment
"
);
o
.
jio
.
removeAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
,
"
_data
"
:
"
My Data
"
,
"
_mimetype
"
:
"
text/plain
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
one
"
,
"
attachment
"
:
"
my_attachment
"
},
"
Remove attachment
"
);
o
.
jio
.
removeAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
},
"
Get document for check
"
);
o
.
jio
.
get
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get attachment for check
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
test
(
"
remove
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
remove1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
remove2
"
}]
});
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove missing document
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
post
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
});
o
.
clock
.
tick
(
1000
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
,
"
_data
"
:
"
My Data
"
,
"
_mimetype
"
:
"
text/plain
"
});
o
.
clock
.
tick
(
1000
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
one
"
},
"
Remove document
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get attachment for check
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
one
"
,
"
_attachment
"
:
"
my_attachment
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get document for check
"
);
o
.
jio
.
get
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
test
(
"
Put
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
put1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
put2
"
}]
});
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
one
"
},
"
Put document
"
);
o
.
jio
.
put
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
},
o
.
f
);
o
.
tick
(
o
)
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meta
"
:
"
data
"
},
"
Get document for check
"
);
o
.
jio
.
get
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
one
"
},
"
Put document again
"
);
o
.
jio
.
put
({
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meow
"
:
"
dog
"
},
o
.
f
);
o
.
tick
(
o
)
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
one
"
,
"
_underscored_meta
"
:
"
uvalue
"
,
"
meow
"
:
"
dog
"
},
"
Get document for check
"
);
o
.
jio
.
get
({
"
_id
"
:
"
one
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
test
(
"
AllDocs
"
,
function
()
{
var
o
=
generateTools
(
this
);
o
.
jio
=
JIO
.
newJio
({
"
type
"
:
"
split
"
,
"
storage_list
"
:
[{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
alldocs1
"
},
{
"
type
"
:
"
local
"
,
"
username
"
:
"
splitstorage
"
,
"
application_name
"
:
"
alldocs2
"
}]
});
for
(
o
.
i
=
0
;
o
.
i
<
5
;
o
.
i
+=
1
)
{
o
.
jio
.
post
({
"
_id
"
:
"
doc
"
+
o
.
i
,
"
_underscored_meta
"
:
"
uvalue
"
+
o
.
i
,
"
meta
"
:
"
data
"
+
o
.
i
});
o
.
clock
.
tick
(
1000
);
}
for
(
o
.
i
=
0
;
o
.
i
<
2
;
o
.
i
+=
1
)
{
o
.
jio
.
putAttachment
({
"
_id
"
:
"
doc
"
+
o
.
i
,
"
_attachment
"
:
"
my_attachment
"
+
o
.
i
,
"
_data
"
:
"
My Data
"
+
o
.
i
,
"
_mimetype
"
:
"
text/plain
"
});
o
.
clock
.
tick
(
1000
);
}
o
.
spy
(
o
,
"
value
"
,
{
"
_id
"
:
"
doc1
"
,
"
_underscored_meta
"
:
"
uvalue1
"
,
"
meta
"
:
"
data1
"
,
"
_attachments
"
:
{
"
my_attachment1
"
:
{
"
length
"
:
8
,
"
content_type
"
:
"
text/plain
"
}
}
},
"
Get document for check
"
);
o
.
jio
.
get
({
"
_id
"
:
"
doc1
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
total_rows
"
:
5
,
"
rows
"
:
[{
"
id
"
:
"
doc0
"
,
"
key
"
:
"
doc0
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
doc1
"
,
"
key
"
:
"
doc1
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
doc2
"
,
"
key
"
:
"
doc2
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
doc3
"
,
"
key
"
:
"
doc3
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
doc4
"
,
"
key
"
:
"
doc4
"
,
"
value
"
:
{}
}]
},
"
AllDocs with document ids only
"
);
o
.
jio
.
allDocs
(
function
(
err
,
response
)
{
if
(
response
&&
Array
.
isArray
(
response
.
rows
))
{
response
.
rows
.
sort
(
function
(
a
,
b
)
{
return
a
.
id
<
b
.
id
?
-
1
:
a
.
id
>
b
.
id
?
1
:
0
;
});
}
o
.
f
(
err
,
response
);
});
o
.
tick
(
o
);
o
.
jio
.
stop
();
});
};
// end thisfun
if
(
window
.
requirejs
)
{
...
...
test/jiotests_withoutrequirejs.html
View file @
3cfc4665
...
...
@@ -38,6 +38,8 @@
</script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/s3storage.js"
>
</script>
<script
type=
"text/javascript"
src=
"../src/jio.storage/splitstorage.js"
>
</script>
<script
type=
"text/javascript"
src=
"./jiotests.js"
></script>
</body>
</html>
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