Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
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
Alain Takoudjou
jio
Commits
9cc2f37f
Commit
9cc2f37f
authored
Oct 24, 2013
by
Tristan Cavelier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
indexstorage updated to JIO v2
parent
3a82fb20
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1040 additions
and
1650 deletions
+1040
-1650
src/jio.storage/indexstorage.js
src/jio.storage/indexstorage.js
+475
-599
test/jio.storage/indexstorage.tests.js
test/jio.storage/indexstorage.tests.js
+565
-1051
No files found.
src/jio.storage/indexstorage.js
View file @
9cc2f37f
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
*/
*/
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, regexp: true */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, regexp: true */
/*global
jIO, define
, complex_queries */
/*global
window, exports, require, define, jIO, RSVP
, complex_queries */
/**
/**
* JIO Index Storage.
* JIO Index Storage.
...
@@ -118,131 +118,23 @@
...
@@ -118,131 +118,23 @@
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
return
define
(
dependencies
,
module
);
}
}
module
(
jIO
,
complex_queries
);
if
(
typeof
exports
===
'
object
'
)
{
}([
'
jio
'
,
'
complex_queries
'
],
function
(
jIO
,
complex_queries
)
{
return
module
(
"
use strict
"
;
exports
,
require
(
'
jio
'
),
var
error_dict
=
{
require
(
'
rsvp
'
),
"
Corrupted Index
"
:
{
require
(
'
complex_queries
'
)
"
status
"
:
24
,
);
"
statusText
"
:
"
Corrupt
"
,
"
error
"
:
"
corrupt
"
,
"
reason
"
:
"
corrupted index database
"
},
"
Corrupted Metadata
"
:
{
"
status
"
:
24
,
"
statusText
"
:
"
Corrupt
"
,
"
error
"
:
"
corrupt
"
,
"
reason
"
:
"
corrupted document
"
},
"
Not Found
"
:
{
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
reason
"
:
"
missing document
"
},
"
Conflict
"
:
{
"
status
"
:
409
,
"
statusText
"
:
"
Conflicts
"
,
"
error
"
:
"
conflicts
"
,
"
reason
"
:
"
already exist
"
},
"
Different Index
"
:
{
"
status
"
:
40
,
"
statusText
"
:
"
Check failed
"
,
"
error
"
:
"
check_failed
"
,
"
reason
"
:
"
incomplete database
"
}
};
/**
* Generate a JIO Error Object
*
* @method generateErrorObject
* @param {String} name The error name
* @param {String} message The error message
* @param {String} [reason] The error reason
* @return {Object} A jIO error object
*/
function
generateErrorObject
(
name
,
message
,
reason
)
{
if
(
!
error_dict
[
name
])
{
return
{
"
status
"
:
0
,
"
statusText
"
:
"
Unknown
"
,
"
error
"
:
"
unknown
"
,
"
message
"
:
message
,
"
reason
"
:
reason
||
"
unknown
"
};
}
return
{
"
status
"
:
error_dict
[
name
].
status
,
"
statusText
"
:
error_dict
[
name
].
statusText
,
"
error
"
:
error_dict
[
name
].
error
,
"
message
"
:
message
,
"
reason
"
:
reason
||
error_dict
[
name
].
reason
};
}
/**
* Get the real type of an object
* @method type
* @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
* @return {string} The new uuid
*/
function
generateUuid
()
{
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
();
}
/**
* Tool to get the date in W3C date format "2011-12-13T14:15:16+01:00"
*
* @param {Any} date The new Date() parameter
* @return {String} The date in W3C date format
*/
function
w3cDate
(
date
)
{
var
d
=
new
Date
(
date
),
offset
=
-
d
.
getTimezoneOffset
();
return
(
d
.
getFullYear
()
+
"
-
"
+
(
d
.
getMonth
()
+
1
)
+
"
-
"
+
d
.
getDate
()
+
"
T
"
+
d
.
getHours
()
+
"
:
"
+
d
.
getMinutes
()
+
"
:
"
+
d
.
getSeconds
()
+
(
offset
<
0
?
"
-
"
:
"
+
"
)
+
(
offset
/
60
)
+
"
:
"
+
(
offset
%
60
)
).
replace
(
/
[
0-9
]
+/g
,
function
(
found
)
{
if
(
found
.
length
<
2
)
{
return
'
0
'
+
found
;
}
return
found
;
});
}
}
window
.
index_storage
=
{};
module
(
window
.
index_storage
,
jIO
,
RSVP
,
complex_queries
);
}([
'
exports
'
,
'
jio
'
,
'
rsvp
'
,
'
complex_queries
'
],
function
(
exports
,
jIO
,
RSVP
,
complex_queries
)
{
"
use strict
"
;
/**
/**
* A JSON Index manipulator
* A JSON Index manipulator
...
@@ -314,7 +206,7 @@
...
@@ -314,7 +206,7 @@
*/
*/
that
.
put
=
function
(
meta
)
{
that
.
put
=
function
(
meta
)
{
var
k
,
needed_meta
=
{},
ok
=
false
;
var
k
,
needed_meta
=
{},
ok
=
false
;
if
(
typeof
meta
.
_id
!==
"
string
"
&&
meta
.
_id
!
==
""
)
{
if
(
typeof
meta
.
_id
!==
"
string
"
||
meta
.
_id
=
==
""
)
{
throw
new
TypeError
(
"
Corrupted Metadata
"
);
throw
new
TypeError
(
"
Corrupted Metadata
"
);
}
}
for
(
k
in
meta
)
{
for
(
k
in
meta
)
{
...
@@ -359,7 +251,8 @@
...
@@ -359,7 +251,8 @@
throw
new
TypeError
(
"
Corrupted Metadata
"
);
throw
new
TypeError
(
"
Corrupted Metadata
"
);
}
}
if
(
typeof
that
.
_location
[
meta
.
_id
]
!==
"
number
"
)
{
if
(
typeof
that
.
_location
[
meta
.
_id
]
!==
"
number
"
)
{
throw
new
ReferenceError
(
"
Not Found
"
);
// throw new ReferenceError("Not Found");
return
;
}
}
that
.
_database
[
that
.
_location
[
meta
.
_id
]]
=
null
;
that
.
_database
[
that
.
_location
[
meta
.
_id
]]
=
null
;
that
.
_free
.
push
(
that
.
_location
[
meta
.
_id
]);
that
.
_free
.
push
(
that
.
_location
[
meta
.
_id
]);
...
@@ -388,7 +281,8 @@
...
@@ -388,7 +281,8 @@
for
(
id
in
that
.
_location
)
{
for
(
id
in
that
.
_location
)
{
if
(
that
.
_location
.
hasOwnProperty
(
id
))
{
if
(
that
.
_location
.
hasOwnProperty
(
id
))
{
database_meta
=
that
.
_database
[
that
.
_location
[
id
]];
database_meta
=
that
.
_database
[
that
.
_location
[
id
]];
if
(
type
(
database_meta
)
!==
"
Object
"
||
if
(
typeof
database_meta
!==
'
object
'
||
Object
.
getPrototypeOf
(
database_meta
||
[])
!==
Object
.
prototype
||
database_meta
.
_id
!==
id
)
{
database_meta
.
_id
!==
id
)
{
throw
new
TypeError
(
"
Corrupted Index
"
);
throw
new
TypeError
(
"
Corrupted Index
"
);
}
}
...
@@ -421,8 +315,11 @@
...
@@ -421,8 +315,11 @@
that
.
checkDocument
=
function
(
doc
)
{
that
.
checkDocument
=
function
(
doc
)
{
var
i
,
key
,
db_doc
;
var
i
,
key
,
db_doc
;
if
(
typeof
that
.
_location
[
doc
.
_id
]
!==
"
number
"
||
if
(
typeof
that
.
_location
[
doc
.
_id
]
!==
"
number
"
)
{
(
db_doc
=
that
.
_database
(
that
.
_location
[
doc
.
_id
]).
_id
)
!==
doc
.
_id
)
{
throw
new
TypeError
(
"
Different Index
"
);
}
db_doc
=
that
.
_database
(
that
.
_location
[
doc
.
_id
]).
_id
;
if
(
db_doc
!==
doc
.
_id
)
{
throw
new
TypeError
(
"
Different Index
"
);
throw
new
TypeError
(
"
Different Index
"
);
}
}
for
(
i
=
0
;
i
<
that
.
_indexing
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
that
.
_indexing
.
length
;
i
+=
1
)
{
...
@@ -442,12 +339,13 @@
...
@@ -442,12 +339,13 @@
var
i
=
0
,
meta
;
var
i
=
0
,
meta
;
that
.
_free
=
[];
that
.
_free
=
[];
that
.
_location
=
{};
that
.
_location
=
{};
if
(
type
(
that
.
_database
)
!==
"
Array
"
)
{
if
(
!
Array
.
isArray
(
that
.
_database
)
)
{
that
.
_database
=
[];
that
.
_database
=
[];
}
}
while
(
i
<
that
.
_database
.
length
)
{
while
(
i
<
that
.
_database
.
length
)
{
meta
=
that
.
_database
[
i
];
meta
=
that
.
_database
[
i
];
if
(
type
(
meta
)
===
"
Object
"
&&
if
(
typeof
meta
===
'
object
'
&&
Object
.
getPrototypeOf
(
meta
||
[])
===
Object
.
prototype
&&
typeof
meta
.
_id
===
"
string
"
&&
meta
.
_id
!==
""
&&
typeof
meta
.
_id
===
"
string
"
&&
meta
.
_id
!==
""
&&
!
that
.
_location
[
meta
.
_id
])
{
!
that
.
_location
[
meta
.
_id
])
{
that
.
_location
[
meta
.
_id
]
=
i
;
that
.
_location
[
meta
.
_id
]
=
i
;
...
@@ -461,10 +359,10 @@
...
@@ -461,10 +359,10 @@
/**
/**
* Returns the serialized version of this object (not cloned)
* Returns the serialized version of this object (not cloned)
*
*
* @method
serialized
* @method
toJSON
* @return {Object} The serialized version
* @return {Object} The serialized version
*/
*/
that
.
serialized
=
function
()
{
that
.
toJSON
=
function
()
{
return
{
return
{
"
indexing
"
:
that
.
_indexing
,
"
indexing
"
:
that
.
_indexing
,
"
free
"
:
that
.
_free
,
"
free
"
:
that
.
_free
,
...
@@ -481,502 +379,480 @@
...
@@ -481,502 +379,480 @@
}
}
/**
/**
* The JIO index storage constructor
* Return the similarity percentage (1 >= p >= 0) between two index lists.
*
* @param {Array} list_a An index list
* @param {Array} list_b Another index list
* @return {Number} The similarity percentage
*/
*/
function
indexStorage
(
spec
,
my
)
{
function
similarityPercentage
(
list_a
,
list_b
)
{
var
that
,
priv
=
{};
var
ai
,
bi
,
count
=
0
;
for
(
ai
=
0
;
ai
<
list_a
.
length
;
ai
+=
1
)
{
for
(
bi
=
0
;
bi
<
list_b
.
length
;
bi
+=
1
)
{
if
(
list_a
[
ai
]
===
list_b
[
bi
])
{
count
+=
1
;
break
;
}
}
}
return
count
/
(
list_a
.
length
>
list_b
.
length
?
list_a
.
length
:
list_b
.
length
);
}
that
=
my
.
basicStorage
(
spec
,
my
);
/**
* The JIO index storage constructor
*
* @class IndexStorage
* @constructor
*/
function
IndexStorage
(
spec
)
{
var
i
;
if
(
!
Array
.
isArray
(
spec
.
indices
))
{
throw
new
TypeError
(
"
IndexStorage 'indices' must be an array of
"
+
"
objects.
"
);
}
this
.
_indices
=
spec
.
indices
;
if
(
typeof
spec
.
sub_storage
!==
'
object
'
||
Object
.
getPrototypeOf
(
spec
.
sub_storage
||
[])
!==
Object
.
prototype
)
{
throw
new
TypeError
(
"
IndexStorage 'sub_storage' must be a storage
"
+
"
description.
"
);
}
// check indices IDs
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
if
(
typeof
this
.
_indices
[
i
].
id
!==
"
string
"
||
this
.
_indices
[
i
].
id
===
""
)
{
throw
new
TypeError
(
"
IndexStorage
"
+
"
'indices[x].id' must be a non empty string
"
);
}
if
(
!
Array
.
isArray
(
this
.
_indices
[
i
].
index
))
{
throw
new
TypeError
(
"
IndexStorage
"
+
"
'indices[x].index' must be a string array
"
);
}
}
this
.
_sub_storage
=
spec
.
sub_storage
;
}
priv
.
indices
=
spec
.
indices
;
/**
priv
.
sub_storage
=
spec
.
sub_storage
;
* Select the good index to use according to a select list.
*
* @method selectIndex
* @param {Array} select_list An array of strings
* @return {Number} The index index
*/
IndexStorage
.
prototype
.
selectIndex
=
function
(
select_list
)
{
var
i
,
tmp
,
selector
=
{
"
index
"
:
0
,
"
similarity
"
:
0
};
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
tmp
=
similarityPercentage
(
select_list
,
this
.
_indices
[
i
].
index
);
if
(
tmp
>
selector
.
similarity
)
{
selector
.
index
=
i
;
selector
.
similarity
=
tmp
;
}
}
return
selector
.
index
;
};
// Overrides
IndexStorage
.
prototype
.
getIndexDatabase
=
function
(
command
,
index
)
{
index
=
this
.
_indices
[
index
];
function
makeNewIndex
()
{
return
new
JSONIndex
({
"
_id
"
:
index
.
id
,
"
_attachment
"
:
index
.
attachment
||
"
body
"
,
"
indexing
"
:
index
.
index
});
}
return
command
.
storage
(
index
.
sub_storage
||
this
.
_sub_storage
).
getAttachment
({
"
_id
"
:
index
.
id
,
"
_attachment
"
:
index
.
attachment
||
"
body
"
}).
then
(
function
(
response
)
{
return
jIO
.
util
.
readBlobAsText
(
response
.
data
);
}).
then
(
function
(
e
)
{
try
{
e
=
JSON
.
parse
(
e
.
target
.
result
);
e
.
_id
=
index
.
id
;
e
.
_attachment
=
index
.
attachment
||
"
body
"
;
}
catch
(
e1
)
{
return
makeNewIndex
();
}
return
new
JSONIndex
(
e
);
},
function
(
err
)
{
if
(
err
.
status
===
404
)
{
return
makeNewIndex
();
// go back to fulfillment channel
}
throw
err
;
// propagate err
});
};
that
.
specToStore
=
function
()
{
IndexStorage
.
prototype
.
getIndexDatabases
=
function
(
command
)
{
return
{
var
i
,
promises
=
[];
"
indices
"
:
priv
.
indices
,
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
"
sub_storage
"
:
priv
.
sub_storage
promises
[
promises
.
length
]
=
this
.
getIndexDatabase
(
command
,
i
);
};
}
};
return
RSVP
.
all
(
promises
);
};
/**
IndexStorage
.
prototype
.
storeIndexDatabase
=
function
(
command
,
database
,
* Return the similarity percentage (1 >= p >= 0) between two index lists.
index
)
{
*
var
that
=
this
;
* @method similarityPercentage
index
=
this
.
_indices
[
index
];
* @param {Array} list_a An index list
function
putAttachment
()
{
* @param {Array} list_b Another index list
return
command
.
storage
(
* @return {Number} The similarity percentage
index
.
sub_storage
||
that
.
_sub_storage
*/
).
putAttachment
({
priv
.
similarityPercentage
=
function
(
list_a
,
list_b
)
{
"
_id
"
:
index
.
id
,
var
ai
,
bi
,
count
=
0
;
"
_attachment
"
:
index
.
attachment
||
"
body
"
,
for
(
ai
=
0
;
ai
<
list_a
.
length
;
ai
+=
1
)
{
"
_data
"
:
JSON
.
stringify
(
database
),
for
(
bi
=
0
;
bi
<
list_b
.
length
;
bi
+=
1
)
{
"
_content_type
"
:
"
application/json
"
if
(
list_a
[
ai
]
===
list_b
[
bi
])
{
});
count
+=
1
;
}
}
function
createDatabaseAndPutAttachmentIfPossible
(
err
)
{
}
if
(
err
.
status
===
404
)
{
return
command
.
storage
(
index
.
sub_storage
||
that
.
_sub_storage
).
post
({
"
_id
"
:
index
.
id
// XXX add metadata to document if necessary
}).
then
(
putAttachment
,
null
,
function
()
{
throw
null
;
// stop post progress propagation
});
}
}
return
count
/
(
list_a
.
length
>
list_b
.
length
?
throw
err
;
list_a
.
length
:
list_b
.
length
);
}
};
return
putAttachment
().
then
(
null
,
createDatabaseAndPutAttachmentIfPossible
);
};
/**
IndexStorage
.
prototype
.
storeIndexDatabases
=
function
(
command
,
databases
)
{
* Select the good index to use according to a select list.
var
i
,
promises
=
[];
*
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
* @method selectIndex
if
(
databases
[
i
]
!==
undefined
)
{
* @param {Array} select_list An array of strings
promises
[
promises
.
length
]
=
* @return {Number} The index index
this
.
storeIndexDatabase
(
command
,
databases
[
i
],
i
);
*/
priv
.
selectIndex
=
function
(
select_list
)
{
var
i
,
tmp
,
selector
=
{
"
index
"
:
0
,
"
similarity
"
:
0
};
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
tmp
=
priv
.
similarityPercentage
(
select_list
,
priv
.
indices
[
i
].
index
);
if
(
tmp
>
selector
.
similarity
)
{
selector
.
index
=
i
;
selector
.
similarity
=
tmp
;
}
}
}
return
selector
.
index
;
}
};
return
RSVP
.
all
(
promises
);
};
/**
* Get a database
*
* @method getIndexDatabase
* @param {Object} option The command option
* @param {Number} number The location in priv.indices
* @param {Function} callback The callback
*/
priv
.
getIndexDatabase
=
function
(
option
,
number
,
callback
)
{
that
.
addJob
(
"
getAttachment
"
,
priv
.
indices
[
number
].
sub_storage
||
priv
.
sub_storage
,
{
"
_id
"
:
priv
.
indices
[
number
].
id
,
"
_attachment
"
:
priv
.
indices
[
number
].
attachment
||
"
body
"
},
option
,
function
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
response
.
_id
=
priv
.
indices
[
number
].
id
;
response
.
_attachment
=
priv
.
indices
[
number
].
attachment
||
"
body
"
;
callback
(
new
JSONIndex
(
response
));
}
catch
(
e
)
{
return
that
.
error
(
generateErrorObject
(
e
.
message
,
"
Repair is necessary
"
,
"
corrupt
"
));
}
},
function
(
err
)
{
if
(
err
.
status
===
404
)
{
callback
(
new
JSONIndex
({
"
_id
"
:
priv
.
indices
[
number
].
id
,
"
_attachment
"
:
priv
.
indices
[
number
].
attachment
||
"
body
"
,
"
indexing
"
:
priv
.
indices
[
number
].
index
}));
return
;
}
err
.
message
=
"
Unable to get index database.
"
;
that
.
error
(
err
);
}
);
};
/**
/**
* Gets a list containing all the databases set in the storage description.
* Generic method for 'post', 'put', 'get' and 'remove'. It delegates the
*
* command to the sub storage and update the databases.
* @method getIndexDatabaseList
*
* @param {Object} option The command option
* @method genericCommand
* @param {Function} callback The result callback(database_list)
* @param {String} method The method to use
*/
* @param {Object} command The JIO command
priv
.
getIndexDatabaseList
=
function
(
option
,
callback
)
{
* @param {Object} metadata The metadata to post
var
i
,
count
=
0
,
callbacks
=
{},
response_list
=
[];
* @param {Object} option The command option
callbacks
.
error
=
function
(
index
)
{
*/
return
function
(
err
)
{
IndexStorage
.
prototype
.
genericCommand
=
function
(
method
,
command
,
if
(
err
.
status
===
404
)
{
metadata
,
option
)
{
response_list
[
index
]
=
new
JSONIndex
({
var
that
=
this
,
generic_response
;
"
_id
"
:
priv
.
indices
[
index
].
id
,
function
updateAndStoreIndexDatabases
(
responses
)
{
"
_attachment
"
:
priv
.
indices
[
index
].
attachment
||
"
body
"
,
var
i
,
database_list
=
responses
[
0
];
"
indexing
"
:
priv
.
indices
[
index
].
index
generic_response
=
responses
[
1
];
});
if
(
method
===
'
get
'
)
{
count
+=
1
;
jIO
.
util
.
dictUpdate
(
metadata
,
generic_response
.
data
);
if
(
count
===
priv
.
indices
.
length
)
{
callback
(
response_list
);
}
return
;
}
err
.
message
=
"
Unable to get index database.
"
;
that
.
error
(
err
);
};
};
callbacks
.
success
=
function
(
index
)
{
return
function
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
response
.
_id
=
priv
.
indices
[
index
].
id
;
response
.
_attachment
=
priv
.
indices
[
index
].
attachment
||
"
body
"
;
response_list
[
index
]
=
new
JSONIndex
(
response
);
}
catch
(
e
)
{
return
that
.
error
(
generateErrorObject
(
e
.
message
,
"
Repair is necessary
"
,
"
corrupt
"
));
}
count
+=
1
;
if
(
count
===
priv
.
indices
.
length
)
{
callback
(
response_list
);
}
};
};
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
that
.
addJob
(
"
getAttachment
"
,
priv
.
indices
[
i
].
sub_storage
||
priv
.
sub_storage
,
{
"
_id
"
:
priv
.
indices
[
i
].
id
,
"
_attachment
"
:
priv
.
indices
[
i
].
attachment
||
"
body
"
},
option
,
callbacks
.
success
(
i
),
callbacks
.
error
(
i
)
);
}
}
};
metadata
.
_id
=
generic_response
.
id
;
if
(
method
===
'
remove
'
)
{
/**
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
* Saves all the databases to the remote(s).
database_list
[
i
].
remove
(
metadata
);
*
* @method storeIndexDatabaseList
* @param {Array} database_list The database list
* @param {Object} option The command option
* @param {Function} callback The result callback(err, response)
*/
priv
.
storeIndexDatabaseList
=
function
(
database_list
,
option
,
callback
)
{
var
i
,
count
=
0
,
count_max
=
0
;
function
onAttachmentResponse
(
response
)
{
count
+=
1
;
if
(
count
===
count_max
)
{
callback
({
"
ok
"
:
true
});
}
}
}
}
else
{
function
onAttachmentError
(
err
)
{
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
err
.
message
=
"
Unable to store index database.
"
;
database_list
[
i
].
put
(
metadata
);
that
.
error
(
err
);
}
function
putAttachment
(
i
)
{
that
.
addJob
(
"
putAttachment
"
,
priv
.
indices
[
i
].
sub_storage
||
priv
.
sub_storage
,
{
"
_id
"
:
database_list
[
i
].
_id
,
"
_attachment
"
:
database_list
[
i
].
_attachment
,
"
_data
"
:
JSON
.
stringify
(
database_list
[
i
].
serialized
()),
"
_mimetype
"
:
"
application/json
"
},
option
,
onAttachmentResponse
,
onAttachmentError
);
}
function
post
(
i
)
{
var
doc
=
priv
.
indices
[
i
].
metadata
||
{};
doc
.
_id
=
database_list
[
i
].
_id
;
that
.
addJob
(
"
post
"
,
// with id
priv
.
indices
[
i
].
sub_storage
||
priv
.
sub_storage
,
doc
,
option
,
function
(
response
)
{
putAttachment
(
i
);
},
function
(
err
)
{
if
(
err
.
status
===
409
)
{
return
putAttachment
(
i
);
}
err
.
message
=
"
Unable to store index database.
"
;
that
.
error
(
err
);
}
);
}
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
if
(
database_list
[
i
]
!==
undefined
)
{
count_max
+=
1
;
post
(
i
);
}
}
}
}
};
return
that
.
storeIndexDatabases
(
command
,
database_list
);
}
/**
function
allProgress
(
progress
)
{
* A generic request method which delegates the request to the sub storage.
if
(
progress
.
index
===
1
)
{
* On response, it will index the document from the request and update all
progress
.
value
.
percentage
*=
0.7
;
// 0 to 70%
* the databases.
command
.
notify
(
progress
.
value
);
*
}
* @method genericRequest
throw
null
;
// stop propagation
* @param {Command} command The JIO command
}
* @param {Function} method The request method
*/
priv
.
genericRequest
=
function
(
command
,
method
)
{
var
doc
=
command
.
cloneDoc
(),
option
=
command
.
cloneOption
();
that
.
addJob
(
method
,
priv
.
sub_storage
,
doc
,
option
,
function
(
response
)
{
switch
(
method
)
{
case
"
post
"
:
case
"
put
"
:
case
"
remove
"
:
doc
.
_id
=
response
.
id
;
priv
.
getIndexDatabaseList
(
option
,
function
(
database_list
)
{
var
i
;
switch
(
method
)
{
case
"
post
"
:
case
"
put
"
:
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
put
(
doc
);
}
break
;
case
"
remove
"
:
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
remove
(
doc
);
}
break
;
default
:
break
;
}
priv
.
storeIndexDatabaseList
(
database_list
,
option
,
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
doc
.
_id
});
});
});
break
;
default
:
that
.
success
(
response
);
break
;
}
},
function
(
err
)
{
return
that
.
error
(
err
);
}
);
};
/**
function
success
()
{
* Post the document metadata and update the index
command
.
success
(
generic_response
);
* @method post
}
* @param {object} command The JIO command
*/
that
.
post
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
post
'
);
};
/**
function
storeProgress
(
progress
)
{
* Update the document metadata and update the index
progress
.
percentage
=
(
0.3
*
progress
.
percentage
)
+
70
;
// 70 to 100%
* @method put
command
.
notify
(
progress
);
* @param {object} command The JIO command
}
*/
that
.
put
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
put
'
);
};
/**
RSVP
.
all
([
* Add an attachment to a document (no index modification)
this
.
getIndexDatabases
(
command
),
* @method putAttachment
command
.
storage
(
this
.
_sub_storage
)[
method
](
metadata
,
option
)
* @param {object} command The JIO command
]).
then
(
updateAndStoreIndexDatabases
,
null
,
allProgress
).
*/
then
(
success
,
command
.
error
,
storeProgress
);
that
.
putAttachment
=
function
(
command
)
{
};
priv
.
genericRequest
(
command
,
'
putAttachment
'
);
};
/**
/**
* Get the document metadata
* Post the document metadata and update the index
* @method get
*
* @param {object} command The JIO command
* @method post
*/
* @param {Object} command The JIO command
that
.
get
=
function
(
command
)
{
* @param {Object} metadata The metadata to post
priv
.
genericRequest
(
command
,
'
get
'
);
* @param {Object} option The command option
};
*/
IndexStorage
.
prototype
.
post
=
function
(
command
,
metadata
,
option
)
{
this
.
genericCommand
(
'
post
'
,
command
,
metadata
,
option
);
};
/**
/**
* Get the attachment.
* Update the document metadata and update the index
* @method getAttachment
*
* @param {object} command The JIO command
* @method put
*/
* @param {Object} command The JIO command
that
.
getAttachment
=
function
(
command
)
{
* @param {Object} metadata The metadata to put
priv
.
genericRequest
(
command
,
'
getAttachment
'
);
* @param {Object} option The command option
};
*/
IndexStorage
.
prototype
.
put
=
function
(
command
,
metadata
,
option
)
{
this
.
genericCommand
(
'
put
'
,
command
,
metadata
,
option
);
};
/**
/**
* Remove document - removing documents updates index!.
* Add an attachment to a document (no index modification)
* @method remove
*
* @param {object} command The JIO command
* @method putAttachment
*/
* @param {Object} command The JIO command
that
.
remove
=
function
(
command
)
{
* @param {Object} param The command parameters
priv
.
genericRequest
(
command
,
'
remove
'
);
* @param {Object} option The command option
};
*/
IndexStorage
.
prototype
.
putAttachment
=
function
(
command
,
param
,
option
)
{
command
.
storage
(
this
.
_sub_storage
).
putAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
/**
/**
* Remove attachment
* Get the document metadata
* @method removeAttachment
*
* @param {object} command The JIO command
* @method get
*/
* @param {Object} command The JIO command
that
.
removeAttachment
=
function
(
command
)
{
* @param {Object} param The command parameters
priv
.
genericRequest
(
command
,
'
removeAttachment
'
);
* @param {Object} option The command option
};
*/
IndexStorage
.
prototype
.
get
=
function
(
command
,
param
,
option
)
{
this
.
genericCommand
(
'
get
'
,
command
,
param
,
option
);
};
/**
/**
* Gets a document list from the substorage
* Get the attachment.
* Options:
*
* - {boolean} include_docs Also retrieve the actual document content.
* @method getAttachment
* @method allDocs
* @param {Object} command The JIO command
* @param {object} command The JIO command
* @param {Object} param The command parameters
*/
* @param {Object} option The command option
that
.
allDocs
=
function
(
command
)
{
*/
var
option
=
command
.
cloneOption
(),
IndexStorage
.
prototype
.
getAttachment
=
function
(
command
,
param
,
option
)
{
index
=
priv
.
selectIndex
(
option
.
select_list
||
[]);
command
.
storage
(
this
.
_sub_storage
).
getAttachment
(
param
,
option
).
// Include docs option is ignored, if you want to get all the document,
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
// don't use index storage!
};
option
.
select_list
=
option
.
select_list
||
[];
/**
option
.
select_list
.
push
(
"
_id
"
);
* Remove document - removing documents updates index!.
priv
.
getIndexDatabase
(
option
,
index
,
function
(
db
)
{
*
var
i
,
id
;
* @method remove
db
=
db
.
_database
;
* @param {Object} command The JIO command
complex_queries
.
QueryFactory
.
create
(
option
.
query
||
''
).
* @param {Object} param The command parameters
exec
(
db
,
option
);
* @param {Object} option The command option
for
(
i
=
0
;
i
<
db
.
length
;
i
+=
1
)
{
*/
id
=
db
[
i
].
_id
;
IndexStorage
.
prototype
.
remove
=
function
(
command
,
param
,
option
)
{
delete
db
[
i
].
_id
;
this
.
genericCommand
(
'
remove
'
,
command
,
param
,
option
);
db
[
i
]
=
{
};
"
id
"
:
id
,
"
key
"
:
id
,
"
value
"
:
db
[
i
],
};
}
that
.
success
({
"
total_rows
"
:
db
.
length
,
"
rows
"
:
db
});
});
};
that
.
check
=
function
(
command
)
{
/**
that
.
repair
(
command
,
true
);
* Remove attachment
};
*
* @method removeAttachment
* @param {Object} command The JIO command
* @param {Object} param The command parameters
* @param {Object} option The command option
*/
IndexStorage
.
prototype
.
removeAttachment
=
function
(
command
,
param
,
option
)
{
command
.
storage
(
this
.
_sub_storage
).
removeAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
priv
.
repairIndexDatabase
=
function
(
command
,
index
,
just_check
)
{
/**
var
i
,
option
=
command
.
cloneOption
();
* Gets a document list from the substorage
that
.
addJob
(
* Options:
'
allDocs
'
,
* - {boolean} include_docs Also retrieve the actual document content.
priv
.
sub_storage
,
* @method allDocs
{},
* @param {object} command The JIO command
{
'
include_docs
'
:
true
},
*/
function
(
response
)
{
IndexStorage
.
prototype
.
allDocs
=
function
(
command
,
param
,
option
)
{
// XXX
var
db_list
=
[],
db
=
new
JSONIndex
({
/*jslint unparam: true */
"
_id
"
:
command
.
getDocId
(),
var
index
=
this
.
selectIndex
(
option
.
select_list
||
[]),
delete_id
;
"
_attachment
"
:
priv
.
indices
[
index
].
attachment
||
"
body
"
,
"
indexing
"
:
priv
.
indices
[
index
].
index
});
for
(
i
=
0
;
i
<
response
.
rows
.
length
;
i
+=
1
)
{
db
.
put
(
response
.
rows
[
i
].
doc
);
}
db_list
[
index
]
=
db
;
if
(
just_check
)
{
priv
.
getIndexDatabase
(
option
,
index
,
function
(
current_db
)
{
if
(
db
.
equals
(
current_db
))
{
return
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
()});
}
return
that
.
error
(
generateErrorObject
(
"
Different Index
"
,
"
Check failed
"
,
"
corrupt index database
"
));
});
}
else
{
priv
.
storeIndexDatabaseList
(
db_list
,
{},
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
()});
});
}
},
function
(
err
)
{
err
.
message
=
"
Unable to repair the index database
"
;
that
.
error
(
err
);
}
);
};
priv
.
repairDocument
=
function
(
command
,
just_check
)
{
// Include docs option is ignored, if you want to get all the document,
var
i
,
option
=
command
.
cloneOption
();
// don't use index storage!
that
.
addJob
(
"
get
"
,
priv
.
sub_storage
,
command
.
cloneDoc
(),
{},
function
(
response
)
{
response
.
_id
=
command
.
getDocId
();
priv
.
getIndexDatabaseList
(
option
,
function
(
database_list
)
{
if
(
just_check
)
{
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
try
{
database_list
[
i
].
checkDocument
(
response
);
}
catch
(
e
)
{
return
that
.
error
(
generateErrorObject
(
e
.
message
,
"
Check failed
"
,
"
corrupt index database
"
));
}
}
that
.
success
({
"
_id
"
:
command
.
getDocId
(),
"
ok
"
:
true
});
}
else
{
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
put
(
response
);
}
priv
.
storeIndexDatabaseList
(
database_list
,
option
,
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
command
.
getDocId
()});
});
}
});
},
function
(
err
)
{
err
.
message
=
"
Unable to repair document
"
;
return
that
.
error
(
err
);
}
);
};
that
.
repair
=
function
(
command
,
just_check
)
{
option
.
select_list
=
(
var
database_index
=
-
1
,
i
;
Array
.
isArray
(
option
.
select_list
)
?
option
.
select_list
:
[]
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
);
if
(
priv
.
indices
[
i
].
id
===
command
.
getDocId
())
{
if
(
option
.
select_list
.
indexOf
(
"
_id
"
)
===
-
1
)
{
database_index
=
i
;
option
.
select_list
.
push
(
"
_id
"
);
break
;
delete_id
=
true
;
}
this
.
getIndexDatabase
(
command
,
index
).
then
(
function
(
db
)
{
var
i
,
id
;
db
=
db
.
_database
;
complex_queries
.
QueryFactory
.
create
(
option
.
query
||
''
).
exec
(
db
,
option
);
for
(
i
=
0
;
i
<
db
.
length
;
i
+=
1
)
{
id
=
db
[
i
].
_id
;
if
(
delete_id
)
{
delete
db
[
i
].
_id
;
}
}
db
[
i
]
=
{
"
id
"
:
id
,
"
value
"
:
db
[
i
]
};
}
}
that
.
addJob
(
command
.
success
(
200
,
{
"
data
"
:
{
"
total_rows
"
:
db
.
length
,
"
rows
"
:
db
}});
"
repair
"
,
},
function
(
err
)
{
priv
.
sub_storage
,
if
(
err
.
status
===
404
)
{
command
.
cloneDoc
(),
return
command
.
success
(
200
,
{
"
data
"
:
{
"
total_rows
"
:
0
,
"
rows
"
:
[]}});
command
.
cloneOption
(),
}
function
(
response
)
{
command
.
error
(
err
);
if
(
database_index
!==
-
1
)
{
});
priv
.
repairIndexDatabase
(
command
,
database_index
,
just_check
);
};
}
else
{
priv
.
repairDocument
(
command
,
just_check
);
}
},
function
(
err
)
{
err
.
message
=
"
Could not repair sub storage
"
;
that
.
error
(
err
);
}
);
};
return
that
;
// IndexStorage.prototype.check = function (command, param, option) { // XXX
}
// this.repair(command, true, param, option);
// };
// IndexStorage.prototype.repairIndexDatabase = function (
// command,
// index,
// just_check,
// param,
// option
// ) { // XXX
// var i, that = this;
// command.storage(this._sub_storage).allDocs({'include_docs': true}).then(
// function (response) {
// var db_list = [], db = new JSONIndex({
// "_id": param._id,
// "_attachment": that._indices[index].attachment || "body",
// "indexing": that._indices[index].index
// });
// for (i = 0; i < response.rows.length; i += 1) {
// db.put(response.rows[i].doc);
// }
// db_list[index] = db;
// if (just_check) {
// this.getIndexDatabase(command, option, index, function (current_db) {
// if (db.equals(current_db)) {
// return command.success({"ok": true, "id": param._id});
// }
// return command.error(
// "conflict",
// "corrupted",
// "Database is not up to date"
// );
// });
// } else {
// that.storeIndexDatabaseList(command, db_list, {}, function () {
// command.success({"ok": true, "id": param._id});
// });
// }
// },
// function (err) {
// err.message = "Unable to repair the index database";
// command.error(err);
// }
// );
// };
// IndexStorage.prototype.repairDocument = function (
// command,
// just_check,
// param,
// option
// ) { // XXX
// var i, that = this;
// command.storage(this._sub_storage).get(param, {}).then(
// function (response) {
// response._id = param._id;
// that.getIndexDatabaseList(command, option, function (database_list) {
// if (just_check) {
// for (i = 0; i < database_list.length; i += 1) {
// try {
// database_list[i].checkDocument(response);
// } catch (e) {
// return command.error(
// "conflict",
// e.message,
// "Corrupt index database"
// );
// }
// }
// command.success({"_id": param._id, "ok": true});
// } else {
// for (i = 0; i < database_list.length; i += 1) {
// database_list[i].put(response);
// }
// that.storeIndexDatabaseList(
// command,
// database_list,
// option,
// function () {
// command.success({"ok": true, "id": param._id});
// }
// );
// }
// });
// },
// function (err) {
// err.message = "Unable to repair document";
// return command.error(err);
// }
// );
// };
// IndexStorage.prototype.repair = function (command, just_check, param,
// option) { // XXX
// var database_index = -1, i, that = this;
// for (i = 0; i < this._indices.length; i += 1) {
// if (this._indices[i].id === param._id) {
// database_index = i;
// break;
// }
// }
// command.storage(this._sub_storage).repair(param, option).then(
// function () {
// if (database_index !== -1) {
// that.repairIndexDatabase(
// command,
// database_index,
// just_check,
// param,
// option
// );
// } else {
// that.repairDocument(command, just_check, param, option);
// }
// },
// function (err) {
// err.message = "Could not repair sub storage";
// command.error(err);
// }
// );
// };
jIO
.
addStorage
(
"
indexed
"
,
IndexStorage
);
exports
.
createDescription
=
function
()
{
// XXX
return
;
};
jIO
.
addStorageType
(
"
indexed
"
,
indexStorage
);
}));
}));
test/jio.storage/indexstorage.tests.js
View file @
9cc2f37f
/*jslint indent: 2, maxlen: 80, nomen: true */
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO, jio_tests, test, ok, deepEqual, sinon */
/*global define, module, test_util, RSVP, jIO, local_storage, test, ok,
deepEqual, stop, start */
// define([module_name], [dependencies], module);
// define([module_name], [dependencies], module);
(
function
(
dependencies
,
module
)
{
(
function
(
dependencies
,
module
)
{
...
@@ -7,1108 +8,621 @@
...
@@ -7,1108 +8,621 @@
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
return
define
(
dependencies
,
module
);
}
}
module
(
jIO
,
jio_tests
);
module
(
test_util
,
RSVP
,
jIO
,
local_storage
);
}([
'
jio
'
,
'
jio_tests
'
,
'
localstorage
'
,
'
indexstorage
'
],
function
(
jIO
,
util
)
{
}([
'
test_util
'
,
'
rsvp
'
,
'
jio
'
,
'
localstorage
'
,
'
indexstorage
'
],
function
(
util
,
RSVP
,
jIO
,
local_storage
)
{
"
use strict
"
;
"
use strict
"
;
function
generateTools
()
{
function
success
(
promise
)
{
return
{
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
,
notify
)
{
clock
:
sinon
.
useFakeTimers
(),
/*jslint unparam: true*/
spy
:
util
.
ospy
,
promise
.
then
(
resolve
,
resolve
,
notify
);
tick
:
util
.
otick
},
function
()
{
};
promise
.
cancel
();
}
module
(
"
IndexStorage
"
);
test
(
"
Post
"
,
function
()
{
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
title
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
ipost
"
,
"
application_name
"
:
"
ipost
"
}
});
});
}
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
/**
if
(
response
)
{
* sequence(thens): Promise
try
{
*
response
=
JSON
.
parse
(
response
);
* Executes a sequence of *then* callbacks. It acts like
}
catch
(
e
)
{
* `smth().then(callback).then(callback)...`. The first callback is called
response
=
"
PARSE ERROR
"
+
response
;
* with no parameter.
*
* Elements of `thens` array can be a function or an array contaning at most
* three *then* callbacks: *onFulfilled*, *onRejected*, *onNotified*.
*
* When `cancel()` is executed, each then promises are cancelled at the same
* time.
*
* @param {Array} thens An array of *then* callbacks
* @return {Promise} A new promise
*/
function
sequence
(
thens
)
{
var
promises
=
[];
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
,
notify
)
{
var
i
;
promises
[
0
]
=
new
RSVP
.
Promise
(
function
(
resolve
)
{
resolve
();
});
for
(
i
=
0
;
i
<
thens
.
length
;
i
+=
1
)
{
if
(
Array
.
isArray
(
thens
[
i
]))
{
promises
[
i
+
1
]
=
promises
[
i
].
then
(
thens
[
i
][
0
],
thens
[
i
][
1
],
thens
[
i
][
2
]);
}
else
{
promises
[
i
+
1
]
=
promises
[
i
].
then
(
thens
[
i
]);
}
}
}
}
o
.
f
(
err
,
response
);
promises
[
i
].
then
(
resolve
,
reject
,
notify
);
};
},
function
()
{
var
i
;
// post without id
for
(
i
=
0
;
i
<
promises
.
length
;
i
+=
1
)
{
o
.
spy
(
o
,
"
jobstatus
"
,
"
done
"
,
"
Post without id
"
);
promises
[
i
].
cancel
();
o
.
jio
.
post
({},
function
(
err
,
response
)
{
o
.
id
=
(
response
||
{}).
id
;
o
.
f
(
err
,
response
);
});
o
.
tick
(
o
);
// post non empty document
o
.
doc
=
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
My Title
"
,
"
year
"
:
2000
,
"
hey
"
:
"
def
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
some_id
"
},
"
Post document
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check document
o
.
fakeIndexA
=
{
"
indexing
"
:
[
"
title
"
],
"
free
"
:
[],
"
location
"
:
{
"
some_id
"
:
0
},
"
database
"
:
[
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
My Title
"
}
]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
=
{
"
indexing
"
:
[
"
title
"
,
"
year
"
],
"
free
"
:
[],
"
location
"
:
{
"
some_id
"
:
0
},
"
database
"
:
[
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
My Title
"
,
"
year
"
:
2000
}
]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// post with escapable characters
o
.
doc
=
{
"
_id
"
:
"
other_id
"
,
"
title
"
:
"
myPost2
"
,
"
findMeA
"
:
"
keyword_*§$%&/()=?
"
,
"
findMeB
"
:
"
keyword_|ð@ł¶đæðſæðæſ³
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
other_id
"
},
"
Post with escapable characters
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// post and document already exists
o
.
doc
=
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
myPost3
"
,
"
findMeA
"
:
"
keyword_ghi
"
,
"
findMeB
"
:
"
keyword_jkl
"
};
o
.
spy
(
o
,
"
status
"
,
409
,
"
Post and document already exists
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
Put
"
,
function
()
{
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iput
"
,
"
application_name
"
:
"
iput
"
}
}
});
});
}
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
module
(
"
IndexStorage
"
);
if
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
}
o
.
f
(
err
,
response
);
};
// put without id
// error 20 -> document id required
o
.
spy
(
o
,
"
status
"
,
20
,
"
Put without id
"
);
o
.
jio
.
put
({},
o
.
f
);
o
.
tick
(
o
);
// put non empty document
o
.
doc
=
{
"
_id
"
:
"
put1
"
,
"
title
"
:
"
myPut1
"
,
"
author
"
:
"
John Doe
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
put1
"
},
"
Put-create document
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check index file
o
.
fakeIndexA
=
{
"
indexing
"
:
[
"
author
"
],
"
free
"
:
[],
"
location
"
:
{
"
put1
"
:
0
},
"
database
"
:
[{
"
_id
"
:
"
put1
"
,
"
author
"
:
"
John Doe
"
}]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
=
{
"
indexing
"
:
[
"
year
"
],
"
free
"
:
[],
"
location
"
:
{},
"
database
"
:
[]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// modify document - modify keyword on index!
o
.
doc
=
{
"
_id
"
:
"
put1
"
,
"
title
"
:
"
myPuttter1
"
,
"
author
"
:
"
Jane Doe
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
put1
"
},
"
Modify existing document
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check index file
o
.
fakeIndexA
.
database
[
0
].
author
=
"
Jane Doe
"
;
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// add new document with same keyword!
o
.
doc
=
{
"
_id
"
:
"
new_doc
"
,
"
title
"
:
"
myPut2
"
,
"
author
"
:
"
Jane Doe
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
new_doc
"
},
"
Add new document with same keyword
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check index file
o
.
fakeIndexA
.
location
.
new_doc
=
1
;
o
.
fakeIndexA
.
database
.
push
({
"
_id
"
:
"
new_doc
"
,
"
author
"
:
"
Jane Doe
"
});
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// add second keyword to index file
o
.
doc
=
{
"
_id
"
:
"
put1
"
,
"
title
"
:
"
myPut2
"
,
"
author
"
:
"
Jane Doe
"
,
"
year
"
:
"
1912
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
put1
"
},
"
add second keyword to index file
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check index file
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
.
location
.
put1
=
0
;
o
.
fakeIndexB
.
database
.
push
({
"
_id
"
:
"
put1
"
,
"
year
"
:
"
1912
"
});
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// remove a keyword from an existing document
o
.
doc
=
{
"
_id
"
:
"
new_doc
"
,
"
title
"
:
"
myPut2
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
new_doc
"
},
"
Remove keyword from existing document
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check index file
delete
o
.
fakeIndexA
.
location
.
new_doc
;
o
.
fakeIndexA
.
database
[
1
]
=
null
;
o
.
fakeIndexA
.
free
.
push
(
1
);
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
Check & Repair
"
,
function
()
{
test
(
"
Scenario
"
,
function
()
{
var
o
=
generateTools
(),
i
;
o
.
jio
=
jIO
.
newJio
({
var
LOCAL_STORAGE_SPEC
=
local_storage
.
createDescription
(
'
indexstorage tests
'
,
'
scenario
'
,
'
memory
'
),
INDEX_STORAGE_SPEC
=
{
"
type
"
:
"
indexed
"
,
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
director
"
]},
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
contributor
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
C
"
,
"
index
"
:
[
"
title
"
]},
{
"
id
"
:
"
D
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
],
],
"
sub_storage
"
:
{
"
sub_storage
"
:
LOCAL_STORAGE_SPEC
"
type
"
:
"
local
"
,
},
option
=
{
"
workspace
"
:
{}},
shared
=
{},
jio_index
,
jio_local
;
"
username
"
:
"
indexstoragerepair
"
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
jio_index
=
jIO
.
createJIO
(
INDEX_STORAGE_SPEC
,
option
);
if
(
response
)
{
jio_local
=
jIO
.
createJIO
(
LOCAL_STORAGE_SPEC
,
option
);
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
delete
response
.
location
;
response
.
database
.
sort
(
function
(
a
,
b
)
{
return
a
.
_id
<
b
.
_id
?
-
1
:
a
.
_id
>
b
.
_id
?
1
:
0
;
});
}
o
.
f
(
err
,
response
);
};
o
.
fakeIndexA
=
{
"
indexing
"
:
[
"
director
"
],
"
free
"
:
[],
"
database
"
:
[]
};
o
.
fakeIndexB
=
{
"
indexing
"
:
[
"
year
"
],
"
free
"
:
[],
"
database
"
:
[]
};
for
(
i
=
0
;
i
<
10
;
i
+=
1
)
{
o
.
jio
.
put
({
"
_id
"
:
"
id
"
+
i
,
"
director
"
:
"
D
"
+
i
,
"
year
"
:
i
,
"
title
"
:
"
T
"
+
i
});
o
.
tmp
=
o
.
fakeIndexA
.
free
.
pop
()
||
o
.
fakeIndexA
.
database
.
length
;
o
.
fakeIndexA
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
"
id
"
+
i
,
"
director
"
:
"
D
"
+
i
};
o
.
tmp
=
o
.
fakeIndexB
.
free
.
pop
()
||
o
.
fakeIndexB
.
database
.
length
;
function
postNewDocument
()
{
o
.
fakeIndexB
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
"
id
"
+
i
,
"
year
"
:
i
}
;
return
jio_index
.
post
({
"
title
"
:
"
Unique ID
"
})
;
}
}
o
.
clock
.
tick
(
5000
);
o
.
spy
(
o
,
"
status
"
,
40
,
"
Check database
"
);
o
.
jio
.
check
({
"
_id
"
:
"
A
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
status
"
,
40
,
"
Check database
"
);
o
.
jio
.
check
({
"
_id
"
:
"
B
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
A
"
,
"
ok
"
:
true
},
"
Repair database
"
);
o
.
jio
.
repair
({
"
_id
"
:
"
A
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
B
"
,
"
ok
"
:
true
},
"
Repair database
"
);
o
.
jio
.
repair
({
"
_id
"
:
"
B
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
A
"
,
"
ok
"
:
true
},
"
Check database again
"
);
o
.
jio
.
check
({
"
_id
"
:
"
A
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
B
"
,
"
ok
"
:
true
},
"
Check database again
"
);
o
.
jio
.
check
({
"
_id
"
:
"
B
"
},
o
.
f
);
o
.
tick
(
o
);
// check index file
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Manually check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Manually check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
jio2
=
jIO
.
newJio
({
"
type
"
:
"
local
"
,
"
username
"
:
"
indexstoragerepair
"
});
o
.
jio2
.
put
({
"
_id
"
:
"
blah
"
,
"
title
"
:
"
t
"
,
"
year
"
:
"
y
"
,
"
director
"
:
"
d
"
});
o
.
clock
.
tick
(
1000
);
util
.
closeAndcleanUpJio
(
o
.
jio2
);
o
.
fakeIndexA
.
database
.
unshift
({
"
_id
"
:
"
blah
"
,
"
director
"
:
"
d
"
});
o
.
fakeIndexB
.
database
.
unshift
({
"
_id
"
:
"
blah
"
,
"
year
"
:
"
y
"
});
o
.
spy
(
o
,
"
status
"
,
40
,
"
Check Document
"
);
o
.
jio
.
check
({
"
_id
"
:
"
blah
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
blah
"
,
"
ok
"
:
true
},
"
Repair Document
"
);
o
.
jio
.
repair
({
"
_id
"
:
"
blah
"
},
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
id
"
:
"
blah
"
,
"
ok
"
:
true
},
"
Check Document again
"
);
o
.
jio
.
repair
({
"
_id
"
:
"
blah
"
},
o
.
f
);
o
.
tick
(
o
);
// check index file
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Manually check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Manually check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
PutAttachment
"
,
function
()
{
function
postNewDocumentTest
(
answer
)
{
var
uuid
=
answer
.
id
;
// not sure these need to be run, because the index does not change
answer
.
id
=
"
<uuid>
"
;
// and only small modifications have been made to handle putAttachment
deepEqual
(
answer
,
{
// tests are from localStorage putAttachment
"
id
"
:
"
<uuid>
"
,
var
o
=
generateTools
();
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
o
.
jio
=
jIO
.
newJio
({
"
status
"
:
201
,
"
type
"
:
"
indexed
"
,
"
statusText
"
:
"
Created
"
"
indices
"
:
[
},
"
Post a new document
"
);
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
ok
(
util
.
isUuid
(
uuid
),
"
New document id should look like
"
+
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
"
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx :
"
+
uuid
);
],
shared
.
created_document_id
=
uuid
;
"
sub_storage
"
:
{
}
"
type
"
:
"
local
"
,
"
username
"
:
"
iputatt
"
,
"
application_name
"
:
"
iputatt
"
}
});
// putAttachment without doc id
// error 20 -> document id required
o
.
spy
(
o
,
"
status
"
,
20
,
"
PutAttachment without doc id
"
);
o
.
jio
.
putAttachment
({},
o
.
f
);
o
.
tick
(
o
);
// putAttachment without attachment id
// error 22 -> attachment id required
o
.
spy
(
o
,
"
status
"
,
22
,
"
PutAttachment without attachment id
"
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
putattmt1
"
},
o
.
f
);
o
.
tick
(
o
);
// putAttachment without document
// error 404 -> not found
o
.
spy
(
o
,
"
status
"
,
404
,
"
PutAttachment without document
"
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
putattmt1
"
,
"
_attachment
"
:
"
putattmt2
"
},
o
.
f
);
o
.
tick
(
o
);
// putAttachment with document
function
getCreatedDocument
()
{
o
.
doc
=
{
"
_id
"
:
"
putattmt1
"
,
"
title
"
:
"
myPutAttmt1
"
};
return
jio_index
.
get
({
"
_id
"
:
shared
.
created_document_id
});
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
putattmt1
"
},
}
"
Put underlying document
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
function
getCreatedDocumentTest
(
answer
)
{
"
ok
"
:
true
,
deepEqual
(
answer
,
{
"
id
"
:
"
putattmt1
"
,
"
data
"
:
{
"
attachment
"
:
"
putattmt2
"
"
_id
"
:
shared
.
created_document_id
,
},
"
PutAttachment with document, without data
"
);
"
title
"
:
"
Unique ID
"
o
.
jio
.
putAttachment
({
"
_id
"
:
"
putattmt1
"
,
"
_attachment
"
:
"
putattmt2
"
},
o
.
f
);
},
o
.
tick
(
o
);
"
id
"
:
shared
.
created_document_id
,
"
method
"
:
"
get
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
Get new document
"
);
}
// check document
// function postSpecificDocuments() {
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
// return success(RSVP.all([
"
jio/localstorage/iputatt/iputatt/putattmt1
"
// jio_index.post({"_id": "b", "title": "Bee", "year": 2013}),
),
{
// jio_index.post({"_id": "ce", "contributor": "DCee"}),
"
_id
"
:
"
putattmt1
"
,
// jio_index.post({"_id": "dee", "format": "text/plain"})
"
title
"
:
"
myPutAttmt1
"
,
// ]));
"
_attachments
"
:
{
// }
"
putattmt2
"
:
{
"
length
"
:
0
,
// function postSpecificDocumentsTest(answers) {
// md5("")
// deepEqual(answers[0], {
"
digest
"
:
"
md5-d41d8cd98f00b204e9800998ecf8427e
"
// "id": "b",
}
// "method": "post",
}
// "result": "success",
},
"
Check document
"
);
// "status": 201,
// "statusText": "Created"
// }, "Post specific document 'b'");
// deepEqual(answers[1], {
// "id": "ce",
// "method": "post",
// "result": "success",
// "status": 201,
// "statusText": "Created"
// }, "Post specific document 'ce'");
// deepEqual(answers[2], {
// "id": "dee",
// "method": "post",
// "result": "success",
// "status": 201,
// "statusText": "Created"
// }, "Post specific document 'dee'");
// }
// XXX the 2 following functions should be replaced by the 2 commented
// previous ones (which don't work yet)
function
postSpecificDocuments
()
{
return
sequence
([
function
()
{
return
jio_index
.
post
({
"
_id
"
:
"
b
"
,
"
title
"
:
"
Bee
"
,
"
year
"
:
2013
});
},
function
()
{
return
jio_index
.
post
({
"
_id
"
:
"
ce
"
,
"
contributor
"
:
"
DCee
"
});
},
function
()
{
return
jio_index
.
post
({
"
_id
"
:
"
dee
"
,
"
format
"
:
"
text/plain
"
});
}]);
}
// check attachment
function
postSpecificDocumentsTest
(
last_answer
)
{
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
deepEqual
(
last_answer
,
{
"
jio/localstorage/iputatt/iputatt/putattmt1/putattmt2
"
"
id
"
:
"
dee
"
,
),
""
,
"
Check attachment
"
);
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
"
status
"
:
201
,
"
statusText
"
:
"
Created
"
},
"
Post documents: 'b', 'ce', 'dee' (testing 'dee' response only)
"
);
}
// update attachment
function
listDocumentsFromIndexContributor
()
{
o
.
spy
(
o
,
"
value
"
,
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
contributor
"
]});
{
"
ok
"
:
true
,
"
id
"
:
"
putattmt1
"
,
"
attachment
"
:
"
putattmt2
"
},
}
"
Update Attachment, with data
"
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
putattmt1
"
,
"
_attachment
"
:
"
putattmt2
"
,
"
_data
"
:
"
abc
"
},
o
.
f
);
o
.
tick
(
o
);
// check document
function
listDocumentsFromIndexContributorTest
(
answer
)
{
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
"
jio/localstorage/iputatt/iputatt/putattmt1
"
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
),
{
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
"
_id
"
:
"
putattmt1
"
,
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
"
title
"
:
"
myPutAttmt1
"
,
);
"
_attachments
"
:
{
});
"
putattmt2
"
:
{
"
length
"
:
3
,
// md5("abc")
"
digest
"
:
"
md5-900150983cd24fb0d6963f7d28e17f72
"
}
}
}
},
"
Check document
"
);
deepEqual
(
answer
,
{
"
data
"
:
{
// check attachment
"
total_rows
"
:
1
,
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
rows
"
:
[{
"
jio/localstorage/iputatt/iputatt/putattmt1/putattmt2
"
"
id
"
:
"
ce
"
,
),
"
abc
"
,
"
Check attachment
"
);
"
value
"
:
{
"
contributor
"
:
"
DCee
"
}
}]
util
.
closeAndcleanUpJio
(
o
.
jio
);
},
});
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
test
(
"
Get
"
,
function
()
{
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 1 document from 'contributor'
"
);
}
// not sure these need to be run, because the index does not change
function
listDocumentsFromIndexTitleYear
()
{
// and only small modifications have been made to handle putAttachment
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
year
"
,
"
title
"
]});
// tests are from localStorage putAttachment
}
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
({
function
listDocumentsFromIndexTitleYearTest
(
answer
)
{
"
type
"
:
"
indexed
"
,
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
"
indices
"
:
[
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
],
);
"
sub_storage
"
:
{
});
"
type
"
:
"
local
"
,
"
username
"
:
"
iget
"
,
"
application_name
"
:
"
iget
"
}
}
});
deepEqual
(
answer
,
{
"
data
"
:
{
// get inexistent document
"
total_rows
"
:
2
,
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent document
"
);
"
rows
"
:
[{
o
.
jio
.
get
({
"
_id
"
:
"
get1
"
},
o
.
f
);
"
id
"
:
"
b
"
,
o
.
tick
(
o
);
"
value
"
:
{
"
title
"
:
"
Bee
"
,
"
year
"
:
2013
}
},
{
// get inexistent attachment
"
id
"
:
shared
.
created_document_id
,
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent attachment
"
);
"
value
"
:
{
"
title
"
:
"
Unique ID
"
}
o
.
jio
.
getAttachment
({
"
_id
"
:
"
get1
"
,
"
_attachment
"
:
"
get2
"
},
o
.
f
);
}]
o
.
tick
(
o
);
},
"
method
"
:
"
allDocs
"
,
// adding a document
"
result
"
:
"
success
"
,
o
.
doc_get1
=
{
"
status
"
:
200
,
"
_id
"
:
"
get1
"
,
"
statusText
"
:
"
Ok
"
"
title
"
:
"
myGet1
"
},
"
List 2 documents from 'year' and 'title'
"
);
};
}
util
.
jsonlocalstorage
.
setItem
(
"
jio/localstorage/iget/iget/get1
"
,
o
.
doc_get1
);
// get document
o
.
spy
(
o
,
"
value
"
,
o
.
doc_get1
,
"
Get document
"
);
o
.
jio
.
get
({
"
_id
"
:
"
get1
"
},
o
.
f
);
o
.
tick
(
o
);
// get inexistent attachment (document exists)
function
listDocumentsFromIndexTitle
()
{
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent attachment (document exists)
"
);
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
title
"
]});
o
.
jio
.
getAttachment
({
"
_id
"
:
"
get1
"
,
"
_attachment
"
:
"
get2
"
},
o
.
f
);
}
o
.
tick
(
o
);
// adding an attachment
function
listDocumentsFromIndexTitleTest
(
answer
)
{
o
.
doc_get1
.
_attachments
=
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
"
get2
"
:
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
"
length
"
:
2
,
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
// md5("de")
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
"
digest
"
:
"
md5-5f02f0889301fd7be1ac972c11bf3e7d
"
);
});
}
}
};
deepEqual
(
answer
,
{
util
.
jsonlocalstorage
.
setItem
(
"
data
"
:
{
"
jio/localstorage/iget/iget/get1
"
,
"
total_rows
"
:
2
,
o
.
doc_get1
"
rows
"
:
[{
);
"
id
"
:
"
b
"
,
util
.
jsonlocalstorage
.
setItem
(
"
jio/localstorage/iget/iget/get1/get2
"
,
"
de
"
);
"
value
"
:
{
"
title
"
:
"
Bee
"
}
},
{
// get attachment
"
id
"
:
shared
.
created_document_id
,
o
.
spy
(
o
,
"
value
"
,
"
de
"
,
"
Get attachment
"
);
"
value
"
:
{
"
title
"
:
"
Unique ID
"
}
o
.
jio
.
getAttachment
({
"
_id
"
:
"
get1
"
,
"
_attachment
"
:
"
get2
"
},
o
.
f
);
}]
o
.
tick
(
o
);
},
"
method
"
:
"
allDocs
"
,
util
.
closeAndcleanUpJio
(
o
.
jio
);
"
result
"
:
"
success
"
,
});
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
test
(
"
Remove
"
,
function
()
{
},
"
List 2 documents from 'title'
"
);
}
// not sure these need to be run, because the index does not change
// and only small modifications have been made to handle putAttachment
// tests are from localStorage putAttachment
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
({
function
listDocumentsFromIndexAuthor
()
{
"
type
"
:
"
indexed
"
,
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
author
"
]});
"
indices
"
:
[
}
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
irem
"
,
"
application_name
"
:
"
irem
"
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
function
listDocumentsFromIndexAuthorTest
(
answer
)
{
if
(
response
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
)
)
{
try
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
re
sponse
=
JSON
.
parse
(
response
);
re
turn
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
}
catch
(
e
)
{
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
response
=
"
PARSE ERROR
"
+
response
;
)
;
}
}
);
}
}
o
.
f
(
err
,
response
);
deepEqual
(
answer
,
{
};
"
data
"
:
{
"
total_rows
"
:
0
,
// remove inexistent document
"
rows
"
:
[]
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove inexistent document
"
);
},
o
.
jio
.
remove
({
"
_id
"
:
"
remove1
"
},
o
.
f
);
"
method
"
:
"
allDocs
"
,
o
.
tick
(
o
);
"
result
"
:
"
success
"
,
"
status
"
:
200
,
// remove inexistent document/attachment
"
statusText
"
:
"
Ok
"
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove inexistent attachment
"
);
},
"
List 0 document from 'author'
"
);
o
.
jio
.
removeAttachment
({
"
_id
"
:
"
remove1
"
,
"
_attachment
"
:
"
remove2
"
},
o
.
f
);
}
o
.
tick
(
o
);
// adding a document
o
.
jio
.
put
({
"
_id
"
:
"
remove1
"
,
"
title
"
:
"
myRemove1
"
,
"
author
"
:
"
Mr. President
"
,
"
year
"
:
"
2525
"
});
o
.
tick
(
o
);
// adding a 2nd document with same keywords
o
.
jio
.
put
({
"
_id
"
:
"
removeAlso
"
,
"
title
"
:
"
myRemove2
"
,
"
author
"
:
"
Martin Mustermann
"
,
"
year
"
:
"
2525
"
});
o
.
tick
(
o
);
// remove document
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
remove1
"
},
"
Remove document
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1
"
},
o
.
f
);
o
.
tick
(
o
);
// check index
o
.
fakeIndexA
=
{
"
indexing
"
:
[
"
author
"
],
"
free
"
:
[
0
],
"
location
"
:
{
"
removeAlso
"
:
1
},
"
database
"
:
[
null
,
{
"
_id
"
:
"
removeAlso
"
,
"
author
"
:
"
Martin Mustermann
"
}]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
=
{
"
indexing
"
:
[
"
year
"
],
"
free
"
:
[
0
],
"
location
"
:
{
"
removeAlso
"
:
1
},
"
database
"
:
[
null
,
{
"
_id
"
:
"
removeAlso
"
,
"
year
"
:
"
2525
"
}]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// check document
o
.
spy
(
o
,
"
status
"
,
404
,
"
Check if document has been removed
"
);
o
.
jio
.
get
({
"
_id
"
:
"
remove1
"
},
o
.
f
);
o
.
tick
(
o
);
// adding a new document
o
.
jio
.
put
({
"
_id
"
:
"
remove3
"
,
"
title
"
:
"
myRemove1
"
,
"
author
"
:
"
Mrs Sunshine
"
,
"
year
"
:
"
1234
"
});
o
.
tick
(
o
);
// adding an attachment
o
.
jio
.
putAttachment
({
"
_id
"
:
"
remove3
"
,
"
_attachment
"
:
"
removeAtt
"
,
"
_mimetype
"
:
"
text/plain
"
,
"
_data
"
:
"
hello
"
});
o
.
tick
(
o
);
// add another attachment
o
.
jio
.
putAttachment
({
"
_id
"
:
"
remove3
"
,
"
_attachment
"
:
"
removeAtt2
"
,
"
_mimetype
"
:
"
text/plain
"
,
"
_data
"
:
"
hello2
"
});
o
.
tick
(
o
);
// remove attachment
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
remove3
"
,
"
attachment
"
:
"
removeAtt2
"
},
"
Remove one of multiple attachment
"
);
o
.
jio
.
removeAttachment
({
"
_id
"
:
"
remove3
"
,
"
_attachment
"
:
"
removeAtt2
"
},
o
.
f
);
o
.
tick
(
o
);
// check index
o
.
fakeIndexA
.
free
=
[];
o
.
fakeIndexA
.
location
.
remove3
=
0
;
o
.
fakeIndexA
.
database
[
0
]
=
{
"
_id
"
:
"
remove3
"
,
"
author
"
:
"
Mrs Sunshine
"
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
.
free
=
[];
o
.
fakeIndexB
.
location
.
remove3
=
0
;
o
.
fakeIndexB
.
database
[
0
]
=
{
"
_id
"
:
"
remove3
"
,
"
year
"
:
"
1234
"
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// remove document and attachment together
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
remove3
"
},
"
Remove one document and attachment together
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove3
"
},
o
.
f
);
o
.
tick
(
o
);
// check index
o
.
fakeIndexA
.
free
=
[
0
];
delete
o
.
fakeIndexA
.
location
.
remove3
;
o
.
fakeIndexA
.
database
[
0
]
=
null
;
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
.
free
=
[
0
];
delete
o
.
fakeIndexB
.
location
.
remove3
;
o
.
fakeIndexB
.
database
[
0
]
=
null
;
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// check attachment
o
.
spy
(
o
,
"
status
"
,
404
,
"
Check if attachment has been removed
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
remove3
"
,
"
_attachment
"
:
"
removeAtt
"
},
o
.
f
);
o
.
tick
(
o
);
// check document
o
.
spy
(
o
,
"
status
"
,
404
,
"
Check if document has been removed
"
);
o
.
jio
.
get
({
"
_id
"
:
"
remove3
"
},
o
.
f
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
AllDocs
"
,
function
()
{
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
({
function
listDocumentsFromNothing
()
{
"
type
"
:
"
indexed
"
,
return
jio_index
.
allDocs
();
"
indices
"
:
[
}
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iall
"
,
"
application_name
"
:
"
iall
"
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
function
listDocumentsFromNothingTest
(
answer
)
{
if
(
response
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
)
)
{
try
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
re
sponse
=
JSON
.
parse
(
response
);
re
turn
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
}
catch
(
e
)
{
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
response
=
"
PARSE ERROR
"
+
response
;
)
;
}
}
);
}
}
o
.
f
(
err
,
response
);
deepEqual
(
answer
,
{
};
"
data
"
:
{
"
total_rows
"
:
1
,
// adding documents
"
rows
"
:
[{
o
.
all1
=
{
"
_id
"
:
"
dragon.doc
"
,
"
id
"
:
"
ce
"
,
"
title
"
:
"
some title
"
,
"
author
"
:
"
Dr. No
"
,
"
year
"
:
"
1968
"
"
value
"
:
{}
};
}]
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
dragon.doc
"
},
"
Put 1
"
);
},
o
.
jio
.
put
(
o
.
all1
,
o
.
f
);
"
method
"
:
"
allDocs
"
,
o
.
tick
(
o
);
"
result
"
:
"
success
"
,
o
.
all2
=
{
"
status
"
:
200
,
"
_id
"
:
"
timemachine
"
,
"
statusText
"
:
"
Ok
"
"
title
"
:
"
hello world
"
,
},
"
List 1 document from first index (`allDocs()`)
"
);
"
author
"
:
"
Dr. Who
"
,
}
"
year
"
:
"
1968
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
timemachine
"
},
"
Put 2
"
);
o
.
jio
.
put
(
o
.
all2
,
o
.
f
);
o
.
tick
(
o
);
o
.
all3
=
{
"
_id
"
:
"
rocket.ppt
"
,
"
title
"
:
"
sunshine.
"
,
"
author
"
:
"
Dr. Snuggles
"
,
"
year
"
:
"
1985
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
rocket.ppt
"
},
"
Put 3
"
);
o
.
jio
.
put
(
o
.
all3
,
o
.
f
);
o
.
tick
(
o
);
o
.
all4
=
{
"
_id
"
:
"
stick.jpg
"
,
"
title
"
:
"
clouds
"
,
"
author
"
:
"
Dr. House
"
,
"
year
"
:
"
2005
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
stick.jpg
"
},
"
Put 4
"
);
o
.
jio
.
put
(
o
.
all4
,
o
.
f
);
o
.
tick
(
o
);
// check index
o
.
fakeIndexA
=
{
"
indexing
"
:
[
"
author
"
],
"
free
"
:
[],
"
location
"
:
{
"
dragon.doc
"
:
0
,
"
timemachine
"
:
1
,
"
rocket.ppt
"
:
2
,
"
stick.jpg
"
:
3
},
"
database
"
:
[
{
"
_id
"
:
"
dragon.doc
"
,
"
author
"
:
"
Dr. No
"
},
{
"
_id
"
:
"
timemachine
"
,
"
author
"
:
"
Dr. Who
"
},
{
"
_id
"
:
"
rocket.ppt
"
,
"
author
"
:
"
Dr. Snuggles
"
},
{
"
_id
"
:
"
stick.jpg
"
,
"
author
"
:
"
Dr. House
"
}
]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
thisShouldBeTheAnswer
=
{
"
rows
"
:
[
{
"
id
"
:
"
dragon.doc
"
,
"
key
"
:
"
dragon.doc
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
timemachine
"
,
"
key
"
:
"
timemachine
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
rocket.ppt
"
,
"
key
"
:
"
rocket.ppt
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
stick.jpg
"
,
"
key
"
:
"
stick.jpg
"
,
"
value
"
:
{}
}
],
"
total_rows
"
:
4
};
o
.
spy
(
o
,
"
value
"
,
o
.
thisShouldBeTheAnswer
,
"
allDocs (served by index)
"
);
o
.
jio
.
allDocs
(
o
.
f
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
AllDocs Complex Queries
"
,
function
()
{
var
o
=
generateTools
(),
i
,
m
=
15
;
o
.
jio
=
jIO
.
newJio
({
function
listDocumentsFromLocal
()
{
"
type
"
:
"
indexed
"
,
return
jio_local
.
allDocs
();
"
indices
"
:
[
}
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
director
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
icomplex
"
,
"
application_name
"
:
"
acomplex
"
}
});
o
.
localpath
=
"
jio/localstorage/icomplex/acomplex
"
;
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
function
listDocumentsFromLocalTest
(
answer
)
{
if
(
response
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
try
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
response
=
JSON
.
parse
(
response
);
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
}
catch
(
e
)
{
a
.
id
.
length
>
b
.
id
.
length
?
1
:
(
response
=
"
PARSE ERROR
"
+
response
;
a
.
id
<
b
.
id
?
-
1
:
a
.
id
>
b
.
id
?
1
:
0
}
)
);
});
}
}
o
.
f
(
err
,
response
);
deepEqual
(
answer
,
{
};
"
data
"
:
{
"
total_rows
"
:
8
,
// sample data
"
rows
"
:
[{
o
.
titles
=
[
"
id
"
:
"
A
"
,
"
Shawshank Redemption
"
,
"
key
"
:
"
A
"
,
"
Godfather
"
,
"
value
"
:
{}
"
Godfather 2
"
,
},
{
"
Pulp Fiction
"
,
"
id
"
:
"
B
"
,
"
The Good, The Bad and The Ugly
"
,
"
key
"
:
"
B
"
,
"
12 Angry Men
"
,
"
value
"
:
{}
"
The Dark Knight
"
,
},
{
"
Schindlers List
"
,
"
id
"
:
"
C
"
,
"
Lord of the Rings - Return of the King
"
,
"
key
"
:
"
C
"
,
"
Fight Club
"
,
"
value
"
:
{}
"
Star Wars Episode V
"
,
},
{
"
Lord Of the Rings - Fellowship of the Ring
"
,
"
id
"
:
"
D
"
,
"
One flew over the Cuckoo's Nest
"
,
"
key
"
:
"
D
"
,
"
Inception
"
,
"
Godfellas
"
"
value
"
:
{}
];
},
{
o
.
years
=
[
"
id
"
:
"
b
"
,
1994
,
"
key
"
:
"
b
"
,
1972
,
"
value
"
:
{}
1974
,
},
{
1994
,
"
id
"
:
"
ce
"
,
1966
,
"
key
"
:
"
ce
"
,
1957
,
"
value
"
:
{}
2008
,
},
{
1993
,
"
id
"
:
"
dee
"
,
2003
,
"
key
"
:
"
dee
"
,
1999
,
"
value
"
:
{}
1980
,
},
{
2001
,
"
id
"
:
shared
.
created_document_id
,
1975
,
"
key
"
:
shared
.
created_document_id
,
2010
,
"
value
"
:
{}
1990
}]
];
},
o
.
director
=
[
"
method
"
:
"
allDocs
"
,
"
Frank Darabont
"
,
"
result
"
:
"
success
"
,
"
Francis Ford Coppola
"
,
"
status
"
:
200
,
"
Francis Ford Coppola
"
,
"
statusText
"
:
"
Ok
"
"
Quentin Tarantino
"
,
},
"
List 8 documents from local (4 document + 4 databases)
"
);
"
Sergio Leone
"
,
"
Sidney Lumet
"
,
"
Christopher Nolan
"
,
"
Steven Spielberg
"
,
"
Peter Jackson
"
,
"
David Fincher
"
,
"
Irvin Kershner
"
,
"
Peter Jackson
"
,
"
Milos Forman
"
,
"
Christopher Nolan
"
,
"
Martin Scorsese
"
];
o
.
fakeIndexA
=
{
"
indexing
"
:
[
"
director
"
],
"
free
"
:
[],
"
location
"
:
{},
"
database
"
:
[]
};
o
.
fakeIndexB
=
{
"
indexing
"
:
[
"
title
"
,
"
year
"
],
"
free
"
:
[],
"
location
"
:
{},
"
database
"
:
[]
};
for
(
i
=
0
;
i
<
m
;
i
+=
1
)
{
o
.
jio
.
put
({
"
_id
"
:
i
.
toString
(),
"
director
"
:
o
.
director
[
i
],
"
year
"
:
o
.
years
[
i
],
"
title
"
:
o
.
titles
[
i
]
});
o
.
tmp
=
o
.
fakeIndexA
.
free
.
pop
()
||
o
.
fakeIndexA
.
database
.
length
;
o
.
fakeIndexA
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
i
.
toString
(),
"
director
"
:
o
.
director
[
i
]
};
o
.
fakeIndexA
.
location
[
i
]
=
o
.
tmp
;
o
.
tmp
=
o
.
fakeIndexB
.
free
.
pop
()
||
o
.
fakeIndexB
.
database
.
length
;
o
.
fakeIndexB
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
i
.
toString
(),
"
year
"
:
o
.
years
[
i
],
"
title
"
:
o
.
titles
[
i
]
};
o
.
fakeIndexB
.
location
[
i
]
=
o
.
tmp
;
o
.
clock
.
tick
(
1000
);
}
}
// o.clock.tick(1000);
// check index file
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
// function removeCreatedDocuments() {
o
.
jio
.
getAttachment
({
// return success(RSVP.all([
"
_id
"
:
"
B
"
,
// jio_index.remove({"_id": shared.created_document_id}),
"
_attachment
"
:
"
body
"
// jio_index.remove({"_id": "b"}),
},
o
.
getAttachmentCallback
);
// jio_index.remove({"_id": "ce"}),
o
.
tick
(
o
);
// jio_index.remove({"_id": "dee"})
// ]));
// }
// function removeCreatedDocumentsTest(answers) {
// deepEqual(answers[0], {
// "id": shared.created_document_id,
// "method": "remove",
// "result": "success",
// "status": 204,
// "statusText": "No Content"
// }, "Remove first document");
// deepEqual(answers[1], {
// "id": "b",
// "method": "remove",
// "result": "success",
// "status": 204,
// "statusText": "No Content"
// }, "Remove document 'b'");
// deepEqual(answers[2], {
// "id": "ce",
// "method": "remove",
// "result": "success",
// "status": 204,
// "statusText": "No Content"
// }, "Remove document 'ce'");
// deepEqual(answers[3], {
// "id": "dee",
// "method": "remove",
// "result": "success",
// "status": 204,
// "statusText": "No Content"
// }, "Remove document 'dee'");
// }
// XXX the 2 following functions should be replaced by the 2 commented
// previous ones (which don't work yet)
function
removeCreatedDocuments
()
{
return
sequence
([
function
()
{
return
jio_index
.
remove
({
"
_id
"
:
shared
.
created_document_id
});
},
function
()
{
return
jio_index
.
remove
({
"
_id
"
:
"
b
"
});
},
function
()
{
return
jio_index
.
remove
({
"
_id
"
:
"
ce
"
});
},
function
()
{
return
jio_index
.
remove
({
"
_id
"
:
"
dee
"
});
}]);
}
// response
function
removeCreatedDocumentsTest
(
last_answer
)
{
o
.
allDocsResponse
=
{};
deepEqual
(
last_answer
,
{
o
.
allDocsResponse
.
rows
=
[];
"
id
"
:
"
dee
"
,
o
.
allDocsResponse
.
total_rows
=
m
;
"
method
"
:
"
remove
"
,
for
(
i
=
0
;
i
<
m
;
i
+=
1
)
{
"
result
"
:
"
success
"
,
o
.
allDocsResponse
.
rows
.
push
({
"
status
"
:
204
,
"
id
"
:
i
.
toString
(),
"
statusText
"
:
"
No Content
"
"
key
"
:
i
.
toString
(),
},
"
Remove first document, 'b', 'ce' and 'dee' (testing 'dee' only)
"
);
"
value
"
:
{},
"
doc
"
:
{
"
_id
"
:
i
.
toString
(),
"
title
"
:
o
.
titles
[
i
],
"
year
"
:
o
.
years
[
i
],
"
director
"
:
o
.
director
[
i
]
}
});
}
}
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
function
listEmptyIndexes
()
{
for
(
i
=
0
;
i
<
o
.
response
.
rows
.
length
;
i
+=
1
)
{
return
RSVP
.
all
([
delete
o
.
response
.
rows
[
i
].
doc
;
success
(
jio_index
.
allDocs
({
"
select_list
"
:
[
"
contributor
"
]})),
success
(
jio_index
.
allDocs
({
"
select_list
"
:
[
"
title
"
]})),
success
(
jio_index
.
allDocs
({
"
select_list
"
:
[
"
title
"
,
"
year
"
]})),
success
(
jio_index
.
allDocs
({
"
select_list
"
:
[
"
author
"
]})),
success
(
jio_index
.
allDocs
())
]);
}
}
// alldocs
function
listEmptyIndexesTest
(
answers
)
{
o
.
spy
(
o
,
"
value
"
,
o
.
response
,
"
AllDocs response generated from index
"
);
deepEqual
(
answers
[
0
],
{
o
.
jio
.
allDocs
(
o
.
f
);
"
data
"
:
{
o
.
tick
(
o
,
1000
);
"
total_rows
"
:
7000
,
"
rows
"
:
[]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List empty indexes 'contributor'
"
);
deepEqual
(
answers
[
1
],
{
"
data
"
:
{
"
total_rows
"
:
7000
,
"
rows
"
:
[]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
List empty indexes 'title'
"
);
deepEqual
(
answers
[
2
],
{
"
data
"
:
{
"
total_rows
"
:
7000
,
"
rows
"
:
[]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
List empty indexes 'title', 'year'
"
);
deepEqual
(
answers
[
3
],
{
"
data
"
:
{
"
total_rows
"
:
7000
,
"
rows
"
:
[]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
List empty indexes 'author'
"
);
deepEqual
(
answers
[
4
],
{
"
data
"
:
{
"
total_rows
"
:
7000
,
"
rows
"
:
[]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
204
,
"
statusText
"
:
"
No Content
"
},
"
List default empty indexes
"
);
}
// complex queries
// // XXX the 2 following functions should be replaced by the 2 commented
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
// // previous ones (which don't work yet)
i
=
0
;
// function removeCreatedDocuments() {
while
(
i
<
o
.
response
.
rows
.
length
)
{
// return sequence([function () {
if
(
o
.
response
.
rows
[
i
].
year
<
1980
)
{
// return jio_index.remove({"_id": shared.created_document_id});
o
.
response
.
rows
.
splice
(
i
,
1
);
// }, function () {
// return jio_index.remove({"_id": "b"});
// }, function () {
// return jio_index.remove({"_id": "ce"});
// }, function () {
// return jio_index.remove({"_id": "dee"});
// }]);
// }
// function removeCreatedDocumentsTest(last_answer) {
// deepEqual(last_answer, {
// "id": "dee",
// "method": "remove",
// "result": "success",
// "status": 204,
// "statusText": "No Content"
// }, "Remove first document, 'b', 'ce' and 'dee' (testing 'dee' only)");
// }
function
unexpectedError
(
error
)
{
if
(
error
instanceof
Error
)
{
deepEqual
([
error
.
name
+
"
:
"
+
error
.
message
,
error
],
"
UNEXPECTED ERROR
"
,
"
Unexpected error
"
);
}
else
{
}
else
{
o
.
response
.
rows
[
i
].
value
=
{
deepEqual
(
error
,
"
UNEXPECTED ERROR
"
,
"
Unexpected error
"
);
"
year
"
:
o
.
response
.
rows
[
i
].
doc
.
year
,
"
title
"
:
o
.
response
.
rows
[
i
].
doc
.
title
};
delete
o
.
response
.
rows
[
i
].
doc
;
i
+=
1
;
}
}
}
}
o
.
response
.
rows
.
sort
(
function
(
a
,
b
)
{
return
(
a
.
value
.
year
>
b
.
value
.
year
?
-
1
:
a
.
value
.
year
<
b
.
value
.
year
?
1
:
0
);
});
o
.
response
.
rows
.
length
=
5
;
o
.
response
.
total_rows
=
5
;
o
.
spy
(
o
,
"
value
"
,
o
.
response
,
"
allDocs (complex queries year >= 1980, index used to do query)
"
);
o
.
jio
.
allDocs
({
// "query":'(year: >= "1980" AND year: < "2000")',
"
query
"
:
'
(year: >= "1980")
'
,
"
limit
"
:
[
0
,
5
],
"
sort_on
"
:
[[
'
year
'
,
'
descending
'
]],
"
select_list
"
:
[
'
title
'
,
'
year
'
]
},
o
.
f
);
o
.
tick
(
o
);
// complex queries
o
.
spy
(
o
,
"
value
"
,
{
"
total_rows
"
:
0
,
"
rows
"
:
[]},
"
allDocs (complex queries year >= 1980, can't use index)
"
);
o
.
jio
.
allDocs
({
// "query":'(year: >= "1980" AND year: < "2000")',
"
query
"
:
'
(year: >= "1980")
'
,
"
limit
"
:
[
0
,
5
],
"
sort_on
"
:
[[
'
year
'
,
'
descending
'
]],
"
select_list
"
:
[
'
director
'
,
'
year
'
]
},
o
.
f
);
o
.
tick
(
o
);
// empty query returns all
stop
();
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
i
=
0
;
// # Post new documents, list them and remove them
while
(
i
<
o
.
response
.
rows
.
length
)
{
// post a 201
o
.
response
.
rows
[
i
].
value
.
title
=
postNewDocument
().
then
(
postNewDocumentTest
).
o
.
response
.
rows
[
i
].
doc
.
title
;
// get 200
delete
o
.
response
.
rows
[
i
].
doc
;
then
(
getCreatedDocument
).
then
(
getCreatedDocumentTest
).
i
+=
1
;
// post b ce dee 201
}
then
(
postSpecificDocuments
).
then
(
postSpecificDocumentsTest
).
o
.
response
.
rows
.
sort
(
function
(
a
,
b
)
{
// allD 200 1 documents from index contributor
return
(
a
.
value
.
title
>
b
.
value
.
title
?
-
1
:
then
(
listDocumentsFromIndexContributor
).
a
.
value
.
title
<
b
.
value
.
title
?
1
:
0
);
then
(
listDocumentsFromIndexContributorTest
).
});
// allD 200 2 documents from index title
o
.
spy
(
o
,
"
value
"
,
o
.
response
,
then
(
listDocumentsFromIndexTitle
).
"
allDocs (empty query in complex query)
"
);
then
(
listDocumentsFromIndexTitleTest
).
o
.
jio
.
allDocs
({
// allD 200 2 documents from index title year
"
sort_on
"
:
[[
'
title
'
,
'
descending
'
]],
then
(
listDocumentsFromIndexTitleYear
).
"
select_list
"
:
[
'
title
'
]
then
(
listDocumentsFromIndexTitleYearTest
).
},
o
.
f
);
// allD 200 0 documents from index author
o
.
tick
(
o
);
then
(
listDocumentsFromIndexAuthor
).
then
(
listDocumentsFromIndexAuthorTest
).
// allD 200 0 documents from nothing (no select_list option)
then
(
listDocumentsFromNothing
).
then
(
listDocumentsFromNothingTest
).
// allD 200 8 documents from local
then
(
listDocumentsFromLocal
).
then
(
listDocumentsFromLocalTest
).
// remove a b ce dee 204
then
(
removeCreatedDocuments
).
then
(
removeCreatedDocumentsTest
).
// allD 200 empty indexes
then
(
listEmptyIndexes
).
then
(
listEmptyIndexesTest
).
// // # Create and update documents, and some attachment and remove them
// // put 201
// then(putNewDocument).then(putNewDocumentTest).
// // get 200
// then(getCreatedDocument2).then(getCreatedDocument2Test).
// // post 409
// then(postSameDocument).then(postSameDocumentTest).
// // putA a 204
// then(createAttachment).then(createAttachmentTest).
// // putA a 204
// then(updateAttachment).then(updateAttachmentTest).
// // putA b 204
// then(createAnotherAttachment).then(createAnotherAttachmentTest).
// // put 204
// then(updateLastDocument).then(updateLastDocumentTest).
// // getA a 200
// then(getFirstAttachment).then(getFirstAttachmentTest).
// // getA b 200
// then(getSecondAttachment).then(getSecondAttachmentTest).
// // get 200
// then(getLastDocument).then(getLastDocumentTest).
// // removeA b 204
// then(removeSecondAttachment).then(removeSecondAttachmentTest).
// // getA b 404
// then(getInexistentSecondAttachment).
// then(getInexistentSecondAttachmentTest).
// // get 200
// then(getOneAttachmentDocument).then(getOneAttachmentDocumentTest).
// // removeA b 404
//then(removeSecondAttachmentAgain).then(removeSecondAttachmentAgainTest).
// // remove 204
// then(removeDocument).then(removeDocumentTest).
// // getA a 404
//then(getInexistentFirstAttachment)
//.then(getInexistentFirstAttachmentTest).
// // get 404
// then(getInexistentDocument).then(getInexistentDocumentTest).
// // remove 404
// then(removeInexistentDocument).then(removeInexistentDocumentTest).
// // check 204
// //then(checkDocument).done(checkDocumentTest).
// //then(checkStorage).done(checkStorageTest).
fail
(
unexpectedError
).
always
(
start
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
});
}));
}));
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