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
Mukul
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
Show 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 @@
*/
/*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.
...
...
@@ -118,131 +118,23 @@
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
}
module
(
jIO
,
complex_queries
);
}([
'
jio
'
,
'
complex_queries
'
],
function
(
jIO
,
complex_queries
)
{
"
use strict
"
;
var
error_dict
=
{
"
Corrupted Index
"
:
{
"
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
;
});
if
(
typeof
exports
===
'
object
'
)
{
return
module
(
exports
,
require
(
'
jio
'
),
require
(
'
rsvp
'
),
require
(
'
complex_queries
'
)
);
}
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
...
...
@@ -314,7 +206,7 @@
*/
that
.
put
=
function
(
meta
)
{
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
"
);
}
for
(
k
in
meta
)
{
...
...
@@ -359,7 +251,8 @@
throw
new
TypeError
(
"
Corrupted Metadata
"
);
}
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
.
_free
.
push
(
that
.
_location
[
meta
.
_id
]);
...
...
@@ -388,7 +281,8 @@
for
(
id
in
that
.
_location
)
{
if
(
that
.
_location
.
hasOwnProperty
(
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
)
{
throw
new
TypeError
(
"
Corrupted Index
"
);
}
...
...
@@ -421,8 +315,11 @@
that
.
checkDocument
=
function
(
doc
)
{
var
i
,
key
,
db_doc
;
if
(
typeof
that
.
_location
[
doc
.
_id
]
!==
"
number
"
||
(
db_doc
=
that
.
_database
(
that
.
_location
[
doc
.
_id
]).
_id
)
!==
doc
.
_id
)
{
if
(
typeof
that
.
_location
[
doc
.
_id
]
!==
"
number
"
)
{
throw
new
TypeError
(
"
Different Index
"
);
}
db_doc
=
that
.
_database
(
that
.
_location
[
doc
.
_id
]).
_id
;
if
(
db_doc
!==
doc
.
_id
)
{
throw
new
TypeError
(
"
Different Index
"
);
}
for
(
i
=
0
;
i
<
that
.
_indexing
.
length
;
i
+=
1
)
{
...
...
@@ -442,12 +339,13 @@
var
i
=
0
,
meta
;
that
.
_free
=
[];
that
.
_location
=
{};
if
(
type
(
that
.
_database
)
!==
"
Array
"
)
{
if
(
!
Array
.
isArray
(
that
.
_database
)
)
{
that
.
_database
=
[];
}
while
(
i
<
that
.
_database
.
length
)
{
meta
=
that
.
_database
[
i
];
if
(
type
(
meta
)
===
"
Object
"
&&
if
(
typeof
meta
===
'
object
'
&&
Object
.
getPrototypeOf
(
meta
||
[])
===
Object
.
prototype
&&
typeof
meta
.
_id
===
"
string
"
&&
meta
.
_id
!==
""
&&
!
that
.
_location
[
meta
.
_id
])
{
that
.
_location
[
meta
.
_id
]
=
i
;
...
...
@@ -461,10 +359,10 @@
/**
* Returns the serialized version of this object (not cloned)
*
* @method
serialized
* @method
toJSON
* @return {Object} The serialized version
*/
that
.
serialized
=
function
()
{
that
.
toJSON
=
function
()
{
return
{
"
indexing
"
:
that
.
_indexing
,
"
free
"
:
that
.
_free
,
...
...
@@ -480,46 +378,59 @@
});
}
/**
* The JIO index storage constructor
*/
function
indexStorage
(
spec
,
my
)
{
var
that
,
priv
=
{};
that
=
my
.
basicStorage
(
spec
,
my
);
priv
.
indices
=
spec
.
indices
;
priv
.
sub_storage
=
spec
.
sub_storage
;
// Overrides
that
.
specToStore
=
function
()
{
return
{
"
indices
"
:
priv
.
indices
,
"
sub_storage
"
:
priv
.
sub_storage
};
};
/**
* Return the similarity percentage (1 >= p >= 0) between two index lists.
*
* @method similarityPercentage
* @param {Array} list_a An index list
* @param {Array} list_b Another index list
* @return {Number} The similarity percentage
*/
priv
.
similarityPercentage
=
function
(
list_a
,
list_b
)
{
function
similarityPercentage
(
list_a
,
list_b
)
{
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
);
};
}
/**
* 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
;
}
/**
* Select the good index to use according to a select list.
...
...
@@ -528,11 +439,10 @@
* @param {Array} select_list An array of strings
* @return {Number} The index index
*/
priv
.
selectIndex
=
function
(
select_list
)
{
IndexStorage
.
prototype
.
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
);
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
;
...
...
@@ -541,293 +451,233 @@
return
selector
.
index
;
};
/**
* 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
)
{
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
{
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
)
{
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
)
{
callback
(
new
JSONIndex
({
"
_id
"
:
priv
.
indices
[
number
].
id
,
"
_attachment
"
:
priv
.
indices
[
number
].
attachment
||
"
body
"
,
"
indexing
"
:
priv
.
indices
[
number
].
index
}));
return
;
return
makeNewIndex
();
// go back to fulfillment channel
}
err
.
message
=
"
Unable to get index database.
"
;
that
.
error
(
err
);
throw
err
;
// propagate err
});
};
IndexStorage
.
prototype
.
getIndexDatabases
=
function
(
command
)
{
var
i
,
promises
=
[];
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
promises
[
promises
.
length
]
=
this
.
getIndexDatabase
(
command
,
i
);
}
);
return
RSVP
.
all
(
promises
);
};
/**
* Gets a list containing all the databases set in the storage description.
*
* @method getIndexDatabaseList
* @param {Object} option The command option
* @param {Function} callback The result callback(database_list)
*/
priv
.
getIndexDatabaseList
=
function
(
option
,
callback
)
{
var
i
,
count
=
0
,
callbacks
=
{},
response_list
=
[];
callbacks
.
error
=
function
(
index
)
{
return
function
(
err
)
{
IndexStorage
.
prototype
.
storeIndexDatabase
=
function
(
command
,
database
,
index
)
{
var
that
=
this
;
index
=
this
.
_indices
[
index
];
function
putAttachment
()
{
return
command
.
storage
(
index
.
sub_storage
||
that
.
_sub_storage
).
putAttachment
({
"
_id
"
:
index
.
id
,
"
_attachment
"
:
index
.
attachment
||
"
body
"
,
"
_data
"
:
JSON
.
stringify
(
database
),
"
_content_type
"
:
"
application/json
"
});
}
function
createDatabaseAndPutAttachmentIfPossible
(
err
)
{
if
(
err
.
status
===
404
)
{
response_list
[
index
]
=
new
JSONIndex
({
"
_id
"
:
priv
.
indices
[
index
].
id
,
"
_attachment
"
:
priv
.
indices
[
index
].
attachment
||
"
body
"
,
"
indexing
"
:
priv
.
indices
[
index
].
index
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
});
count
+=
1
;
if
(
count
===
priv
.
indices
.
length
)
{
callback
(
response_list
);
}
return
;
throw
err
;
}
err
.
message
=
"
Unable to get index database.
"
;
that
.
error
(
err
);
return
putAttachment
().
then
(
null
,
createDatabaseAndPutAttachmentIfPossible
);
};
};
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
);
IndexStorage
.
prototype
.
storeIndexDatabases
=
function
(
command
,
databases
)
{
var
i
,
promises
=
[];
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
if
(
databases
[
i
]
!==
undefined
)
{
promises
[
promises
.
length
]
=
this
.
storeIndexDatabase
(
command
,
databases
[
i
],
i
);
}
};
};
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
)
);
}
return
RSVP
.
all
(
promises
);
};
/**
* Saves all the databases to the remote(s).
* Generic method for 'post', 'put', 'get' and 'remove'. It delegates the
* command to the sub storage and update the databases.
*
* @method storeIndexDatabaseList
* @param {Array} database_list The database list
* @method genericCommand
* @param {String} method The method to use
* @param {Object} command The JIO command
* @param {Object} metadata The metadata to post
* @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
});
}
}
function
onAttachmentError
(
err
)
{
err
.
message
=
"
Unable to store index database.
"
;
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
);
IndexStorage
.
prototype
.
genericCommand
=
function
(
method
,
command
,
metadata
,
option
)
{
var
that
=
this
,
generic_response
;
function
updateAndStoreIndexDatabases
(
responses
)
{
var
i
,
database_list
=
responses
[
0
];
generic_response
=
responses
[
1
];
if
(
method
===
'
get
'
)
{
jIO
.
util
.
dictUpdate
(
metadata
,
generic_response
.
data
);
}
metadata
.
_id
=
generic_response
.
id
;
if
(
method
===
'
remove
'
)
{
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
remove
(
metadata
);
}
);
}
else
{
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
put
(
metadata
);
}
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
);
}
};
/**
* A generic request method which delegates the request to the sub storage.
* On response, it will index the document from the request and update all
* the databases.
*
* @method genericRequest
* @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
);
function
allProgress
(
progress
)
{
if
(
progress
.
index
===
1
)
{
progress
.
value
.
percentage
*=
0.7
;
// 0 to 70%
command
.
notify
(
progress
.
value
);
}
break
;
case
"
remove
"
:
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
remove
(
doc
);
throw
null
;
// stop propagation
}
break
;
default
:
break
;
}
priv
.
storeIndexDatabaseList
(
database_list
,
option
,
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
doc
.
_id
});
});
});
break
;
default
:
that
.
success
(
response
);
break
;
function
success
()
{
command
.
success
(
generic_response
);
}
},
function
(
err
)
{
return
that
.
error
(
err
);
function
storeProgress
(
progress
)
{
progress
.
percentage
=
(
0.3
*
progress
.
percentage
)
+
70
;
// 70 to 100%
command
.
notify
(
progress
);
}
);
RSVP
.
all
([
this
.
getIndexDatabases
(
command
),
command
.
storage
(
this
.
_sub_storage
)[
method
](
metadata
,
option
)
]).
then
(
updateAndStoreIndexDatabases
,
null
,
allProgress
).
then
(
success
,
command
.
error
,
storeProgress
);
};
/**
* Post the document metadata and update the index
*
* @method post
* @param {object} command The JIO command
* @param {Object} command The JIO command
* @param {Object} metadata The metadata to post
* @param {Object} option The command option
*/
that
.
post
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
post
'
);
IndexStorage
.
prototype
.
post
=
function
(
command
,
metadata
,
option
)
{
this
.
genericCommand
(
'
post
'
,
command
,
metadata
,
option
);
};
/**
* Update the document metadata and update the index
*
* @method put
* @param {object} command The JIO command
* @param {Object} command The JIO command
* @param {Object} metadata The metadata to put
* @param {Object} option The command option
*/
that
.
put
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
put
'
);
IndexStorage
.
prototype
.
put
=
function
(
command
,
metadata
,
option
)
{
this
.
genericCommand
(
'
put
'
,
command
,
metadata
,
option
);
};
/**
* Add an attachment to a document (no index modification)
*
* @method putAttachment
* @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
.
putAttachment
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
putAttachment
'
);
IndexStorage
.
prototype
.
putAttachment
=
function
(
command
,
param
,
option
)
{
command
.
storage
(
this
.
_sub_storage
).
putAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
/**
* Get the document metadata
*
* @method get
* @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
.
get
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
get
'
);
IndexStorage
.
prototype
.
get
=
function
(
command
,
param
,
option
)
{
this
.
genericCommand
(
'
get
'
,
command
,
param
,
option
);
};
/**
* Get the attachment.
*
* @method getAttachment
* @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
.
getAttachment
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
getAttachment
'
);
IndexStorage
.
prototype
.
getAttachment
=
function
(
command
,
param
,
option
)
{
command
.
storage
(
this
.
_sub_storage
).
getAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
/**
* Remove document - removing documents updates index!.
*
* @method remove
* @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
.
remove
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
remove
'
);
IndexStorage
.
prototype
.
remove
=
function
(
command
,
param
,
option
)
{
this
.
genericCommand
(
'
remove
'
,
command
,
param
,
option
);
};
/**
* Remove attachment
*
* @method removeAttachment
* @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
.
removeAttachment
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
removeAttachment
'
);
IndexStorage
.
prototype
.
removeAttachment
=
function
(
command
,
param
,
option
)
{
command
.
storage
(
this
.
_sub_storage
).
removeAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
/**
...
...
@@ -837,146 +687,172 @@
* @method allDocs
* @param {object} command The JIO command
*/
that
.
allDocs
=
function
(
command
)
{
var
option
=
command
.
cloneOption
(),
index
=
priv
.
selectIndex
(
option
.
select_list
||
[]);
IndexStorage
.
prototype
.
allDocs
=
function
(
command
,
param
,
option
)
{
// XXX
/*jslint unparam: true */
var
index
=
this
.
selectIndex
(
option
.
select_list
||
[]),
delete_id
;
// Include docs option is ignored, if you want to get all the document,
// don't use index storage!
option
.
select_list
=
option
.
select_list
||
[];
option
.
select_list
=
(
Array
.
isArray
(
option
.
select_list
)
?
option
.
select_list
:
[]
);
if
(
option
.
select_list
.
indexOf
(
"
_id
"
)
===
-
1
)
{
option
.
select_list
.
push
(
"
_id
"
);
priv
.
getIndexDatabase
(
option
,
index
,
function
(
db
)
{
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
,
"
key
"
:
id
,
"
value
"
:
db
[
i
],
};
}
that
.
success
({
"
total_rows
"
:
db
.
length
,
"
rows
"
:
db
});
});
"
value
"
:
db
[
i
]
};
that
.
check
=
function
(
command
)
{
that
.
repair
(
command
,
true
);
};
priv
.
repairIndexDatabase
=
function
(
command
,
index
,
just_check
)
{
var
i
,
option
=
command
.
cloneOption
();
that
.
addJob
(
'
allDocs
'
,
priv
.
sub_storage
,
{},
{
'
include_docs
'
:
true
},
function
(
response
)
{
var
db_list
=
[],
db
=
new
JSONIndex
({
"
_id
"
:
command
.
getDocId
(),
"
_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
)
{
var
i
,
option
=
command
.
cloneOption
();
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
()});
});
command
.
success
(
200
,
{
"
data
"
:
{
"
total_rows
"
:
db
.
length
,
"
rows
"
:
db
}});
},
function
(
err
)
{
if
(
err
.
status
===
404
)
{
return
command
.
success
(
200
,
{
"
data
"
:
{
"
total_rows
"
:
0
,
"
rows
"
:
[]}});
}
command
.
error
(
err
);
});
},
function
(
err
)
{
err
.
message
=
"
Unable to repair document
"
;
return
that
.
error
(
err
);
}
);
};
that
.
repair
=
function
(
command
,
just_check
)
{
var
database_index
=
-
1
,
i
;
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
if
(
priv
.
indices
[
i
].
id
===
command
.
getDocId
())
{
database_index
=
i
;
break
;
}
}
that
.
addJob
(
"
repair
"
,
priv
.
sub_storage
,
command
.
cloneDoc
(),
command
.
cloneOption
(),
function
(
response
)
{
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
);
}
);
// 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
;
};
return
that
;
}
jIO
.
addStorageType
(
"
indexed
"
,
indexStorage
);
}));
test/jio.storage/indexstorage.tests.js
View file @
9cc2f37f
/*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);
(
function
(
dependencies
,
module
)
{
...
...
@@ -7,1108 +8,621 @@
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
}
module
(
jIO
,
jio_tests
);
}([
'
jio
'
,
'
jio_tests
'
,
'
localstorage
'
,
'
indexstorage
'
],
function
(
jIO
,
util
)
{
module
(
test_util
,
RSVP
,
jIO
,
local_storage
);
}([
'
test_util
'
,
'
rsvp
'
,
'
jio
'
,
'
localstorage
'
,
'
indexstorage
'
],
function
(
util
,
RSVP
,
jIO
,
local_storage
)
{
"
use strict
"
;
function
generateTools
()
{
return
{
clock
:
sinon
.
useFakeTimers
(),
spy
:
util
.
ospy
,
tick
:
util
.
otick
};
function
success
(
promise
)
{
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
,
notify
)
{
/*jslint unparam: true*/
promise
.
then
(
resolve
,
resolve
,
notify
);
},
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
"
}
/**
* sequence(thens): Promise
*
* Executes a sequence of *then* callbacks. It acts like
* `smth().then(callback).then(callback)...`. The first callback is called
* 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
();
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
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
);
};
// post without id
o
.
spy
(
o
,
"
jobstatus
"
,
"
done
"
,
"
Post without id
"
);
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
"
promises
[
i
].
then
(
resolve
,
reject
,
notify
);
},
function
()
{
var
i
;
for
(
i
=
0
;
i
<
promises
.
length
;
i
+=
1
)
{
promises
[
i
].
cancel
();
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
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
);
});
module
(
"
IndexStorage
"
);
test
(
"
Check & Repair
"
,
function
()
{
var
o
=
generateTools
(),
i
;
test
(
"
Scenario
"
,
function
()
{
o
.
jio
=
jIO
.
newJio
({
var
LOCAL_STORAGE_SPEC
=
local_storage
.
createDescription
(
'
indexstorage tests
'
,
'
scenario
'
,
'
memory
'
),
INDEX_STORAGE_SPEC
=
{
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
director
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
contributor
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
C
"
,
"
index
"
:
[
"
title
"
]},
{
"
id
"
:
"
D
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
indexstoragerepair
"
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
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
);
};
"
sub_storage
"
:
LOCAL_STORAGE_SPEC
},
option
=
{
"
workspace
"
:
{}},
shared
=
{},
jio_index
,
jio_local
;
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
});
jio_index
=
jIO
.
createJIO
(
INDEX_STORAGE_SPEC
,
option
);
jio_local
=
jIO
.
createJIO
(
LOCAL_STORAGE_SPEC
,
option
);
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
;
o
.
fakeIndexB
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
"
id
"
+
i
,
"
year
"
:
i
};
function
postNewDocument
()
{
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
()
{
// 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
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iputatt
"
,
"
application_name
"
:
"
iputatt
"
function
postNewDocumentTest
(
answer
)
{
var
uuid
=
answer
.
id
;
answer
.
id
=
"
<uuid>
"
;
deepEqual
(
answer
,
{
"
id
"
:
"
<uuid>
"
,
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
"
status
"
:
201
,
"
statusText
"
:
"
Created
"
},
"
Post a new document
"
);
ok
(
util
.
isUuid
(
uuid
),
"
New document id should look like
"
+
"
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx :
"
+
uuid
);
shared
.
created_document_id
=
uuid
;
}
});
// 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
o
.
doc
=
{
"
_id
"
:
"
putattmt1
"
,
"
title
"
:
"
myPutAttmt1
"
};
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
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
putattmt1
"
,
"
attachment
"
:
"
putattmt2
"
},
"
PutAttachment with document, without data
"
);
o
.
jio
.
putAttachment
({
"
_id
"
:
"
putattmt1
"
,
"
_attachment
"
:
"
putattmt2
"
},
o
.
f
);
o
.
tick
(
o
);
// check document
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
jio/localstorage/iputatt/iputatt/putattmt1
"
),
{
"
_id
"
:
"
putattmt1
"
,
"
title
"
:
"
myPutAttmt1
"
,
"
_attachments
"
:
{
"
putattmt2
"
:
{
"
length
"
:
0
,
// md5("")
"
digest
"
:
"
md5-d41d8cd98f00b204e9800998ecf8427e
"
}
function
getCreatedDocument
()
{
return
jio_index
.
get
({
"
_id
"
:
shared
.
created_document_id
});
}
},
"
Check document
"
);
// check attachment
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
jio/localstorage/iputatt/iputatt/putattmt1/putattmt2
"
),
""
,
"
Check attachment
"
);
// update attachment
o
.
spy
(
o
,
"
value
"
,
{
"
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
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
jio/localstorage/iputatt/iputatt/putattmt1
"
),
{
"
_id
"
:
"
putattmt1
"
,
"
title
"
:
"
myPutAttmt1
"
,
"
_attachments
"
:
{
"
putattmt2
"
:
{
"
length
"
:
3
,
// md5("abc")
"
digest
"
:
"
md5-900150983cd24fb0d6963f7d28e17f72
"
function
getCreatedDocumentTest
(
answer
)
{
deepEqual
(
answer
,
{
"
data
"
:
{
"
_id
"
:
shared
.
created_document_id
,
"
title
"
:
"
Unique ID
"
},
"
id
"
:
shared
.
created_document_id
,
"
method
"
:
"
get
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
Get new document
"
);
}
// function postSpecificDocuments() {
// return success(RSVP.all([
// jio_index.post({"_id": "b", "title": "Bee", "year": 2013}),
// jio_index.post({"_id": "ce", "contributor": "DCee"}),
// jio_index.post({"_id": "dee", "format": "text/plain"})
// ]));
// }
// function postSpecificDocumentsTest(answers) {
// deepEqual(answers[0], {
// "id": "b",
// "method": "post",
// "result": "success",
// "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
"
});
}]);
}
function
postSpecificDocumentsTest
(
last_answer
)
{
deepEqual
(
last_answer
,
{
"
id
"
:
"
dee
"
,
"
method
"
:
"
post
"
,
"
result
"
:
"
success
"
,
"
status
"
:
201
,
"
statusText
"
:
"
Created
"
},
"
Post documents: 'b', 'ce', 'dee' (testing 'dee' response only)
"
);
}
function
listDocumentsFromIndexContributor
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
contributor
"
]});
}
function
listDocumentsFromIndexContributorTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
);
});
}
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
1
,
"
rows
"
:
[{
"
id
"
:
"
ce
"
,
"
value
"
:
{
"
contributor
"
:
"
DCee
"
}
}]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 1 document from 'contributor'
"
);
}
},
"
Check document
"
);
// check attachment
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
jio/localstorage/iputatt/iputatt/putattmt1/putattmt2
"
),
"
abc
"
,
"
Check attachment
"
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
Get
"
,
function
()
{
// 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
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iget
"
,
"
application_name
"
:
"
iget
"
function
listDocumentsFromIndexTitleYear
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
year
"
,
"
title
"
]});
}
});
// get inexistent document
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent document
"
);
o
.
jio
.
get
({
"
_id
"
:
"
get1
"
},
o
.
f
);
o
.
tick
(
o
);
// get inexistent attachment
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent attachment
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
get1
"
,
"
_attachment
"
:
"
get2
"
},
o
.
f
);
o
.
tick
(
o
);
// adding a document
o
.
doc_get1
=
{
"
_id
"
:
"
get1
"
,
"
title
"
:
"
myGet1
"
};
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)
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent attachment (document exists)
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
get1
"
,
"
_attachment
"
:
"
get2
"
},
o
.
f
);
o
.
tick
(
o
);
// adding an attachment
o
.
doc_get1
.
_attachments
=
{
"
get2
"
:
{
"
length
"
:
2
,
// md5("de")
"
digest
"
:
"
md5-5f02f0889301fd7be1ac972c11bf3e7d
"
}
};
util
.
jsonlocalstorage
.
setItem
(
"
jio/localstorage/iget/iget/get1
"
,
o
.
doc_get1
function
listDocumentsFromIndexTitleYearTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
);
util
.
jsonlocalstorage
.
setItem
(
"
jio/localstorage/iget/iget/get1/get2
"
,
"
de
"
);
// get attachment
o
.
spy
(
o
,
"
value
"
,
"
de
"
,
"
Get attachment
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
get1
"
,
"
_attachment
"
:
"
get2
"
},
o
.
f
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
Remove
"
,
function
()
{
// 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
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
irem
"
,
"
application_name
"
:
"
irem
"
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
2
,
"
rows
"
:
[{
"
id
"
:
"
b
"
,
"
value
"
:
{
"
title
"
:
"
Bee
"
,
"
year
"
:
2013
}
},
{
"
id
"
:
shared
.
created_document_id
,
"
value
"
:
{
"
title
"
:
"
Unique ID
"
}
}]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 2 documents from 'year' and 'title'
"
);
}
o
.
f
(
err
,
response
);
};
// remove inexistent document
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove inexistent document
"
);
o
.
jio
.
remove
({
"
_id
"
:
"
remove1
"
},
o
.
f
);
o
.
tick
(
o
);
// remove inexistent document/attachment
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove inexistent attachment
"
);
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
);
function
listDocumentsFromIndexTitle
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
title
"
]});
}
// adding a 2nd document with same keywords
o
.
jio
.
put
({
"
_id
"
:
"
removeAlso
"
,
"
title
"
:
"
myRemove2
"
,
"
author
"
:
"
Martin Mustermann
"
,
"
year
"
:
"
2525
"
function
listDocumentsFromIndexTitleTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
);
});
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
}
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
2
,
"
rows
"
:
[{
"
id
"
:
"
b
"
,
"
value
"
:
{
"
title
"
:
"
Bee
"
}
},
{
"
id
"
:
shared
.
created_document_id
,
"
value
"
:
{
"
title
"
:
"
Unique ID
"
}
}]
},
"
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
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iall
"
,
"
application_name
"
:
"
iall
"
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 2 documents from 'title'
"
);
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
function
listDocumentsFromIndexAuthor
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
author
"
]});
}
o
.
f
(
err
,
response
);
};
// adding documents
o
.
all1
=
{
"
_id
"
:
"
dragon.doc
"
,
"
title
"
:
"
some title
"
,
"
author
"
:
"
Dr. No
"
,
"
year
"
:
"
1968
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
dragon.doc
"
},
"
Put 1
"
);
o
.
jio
.
put
(
o
.
all1
,
o
.
f
);
o
.
tick
(
o
);
o
.
all2
=
{
"
_id
"
:
"
timemachine
"
,
"
title
"
:
"
hello world
"
,
"
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
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
director
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
icomplex
"
,
"
application_name
"
:
"
acomplex
"
}
function
listDocumentsFromIndexAuthorTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
);
});
o
.
localpath
=
"
jio/localstorage/icomplex/acomplex
"
;
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
0
,
"
rows
"
:
[]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 0 document from 'author'
"
);
}
o
.
f
(
err
,
response
);
};
// sample data
o
.
titles
=
[
"
Shawshank Redemption
"
,
"
Godfather
"
,
"
Godfather 2
"
,
"
Pulp Fiction
"
,
"
The Good, The Bad and The Ugly
"
,
"
12 Angry Men
"
,
"
The Dark Knight
"
,
"
Schindlers List
"
,
"
Lord of the Rings - Return of the King
"
,
"
Fight Club
"
,
"
Star Wars Episode V
"
,
"
Lord Of the Rings - Fellowship of the Ring
"
,
"
One flew over the Cuckoo's Nest
"
,
"
Inception
"
,
"
Godfellas
"
];
o
.
years
=
[
1994
,
1972
,
1974
,
1994
,
1966
,
1957
,
2008
,
1993
,
2003
,
1999
,
1980
,
2001
,
1975
,
2010
,
1990
];
o
.
director
=
[
"
Frank Darabont
"
,
"
Francis Ford Coppola
"
,
"
Francis Ford Coppola
"
,
"
Quentin Tarantino
"
,
"
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
);
function
listDocumentsFromNothing
()
{
return
jio_index
.
allDocs
();
}
// 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
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// response
o
.
allDocsResponse
=
{};
o
.
allDocsResponse
.
rows
=
[];
o
.
allDocsResponse
.
total_rows
=
m
;
for
(
i
=
0
;
i
<
m
;
i
+=
1
)
{
o
.
allDocsResponse
.
rows
.
push
({
"
id
"
:
i
.
toString
(),
"
key
"
:
i
.
toString
(),
"
value
"
:
{},
"
doc
"
:
{
"
_id
"
:
i
.
toString
(),
"
title
"
:
o
.
titles
[
i
],
"
year
"
:
o
.
years
[
i
],
"
director
"
:
o
.
director
[
i
]
}
function
listDocumentsFromNothingTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
);
});
}
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
for
(
i
=
0
;
i
<
o
.
response
.
rows
.
length
;
i
+=
1
)
{
delete
o
.
response
.
rows
[
i
].
doc
;
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
1
,
"
rows
"
:
[{
"
id
"
:
"
ce
"
,
"
value
"
:
{}
}]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 1 document from first index (`allDocs()`)
"
);
}
// alldocs
o
.
spy
(
o
,
"
value
"
,
o
.
response
,
"
AllDocs response generated from index
"
);
o
.
jio
.
allDocs
(
o
.
f
);
o
.
tick
(
o
,
1000
);
// complex queries
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
i
=
0
;
while
(
i
<
o
.
response
.
rows
.
length
)
{
if
(
o
.
response
.
rows
[
i
].
year
<
1980
)
{
o
.
response
.
rows
.
splice
(
i
,
1
);
}
else
{
o
.
response
.
rows
[
i
].
value
=
{
"
year
"
:
o
.
response
.
rows
[
i
].
doc
.
year
,
"
title
"
:
o
.
response
.
rows
[
i
].
doc
.
title
};
delete
o
.
response
.
rows
[
i
].
doc
;
i
+=
1
;
}
function
listDocumentsFromLocal
()
{
return
jio_local
.
allDocs
();
}
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
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
i
=
0
;
while
(
i
<
o
.
response
.
rows
.
length
)
{
o
.
response
.
rows
[
i
].
value
.
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
.
title
>
b
.
value
.
title
?
-
1
:
a
.
value
.
title
<
b
.
value
.
title
?
1
:
0
);
function
listDocumentsFromLocalTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
(
a
.
id
<
b
.
id
?
-
1
:
a
.
id
>
b
.
id
?
1
:
0
)
);
});
o
.
spy
(
o
,
"
value
"
,
o
.
response
,
"
allDocs (empty query in complex query)
"
);
o
.
jio
.
allDocs
({
"
sort_on
"
:
[[
'
title
'
,
'
descending
'
]],
"
select_list
"
:
[
'
title
'
]
},
o
.
f
);
o
.
tick
(
o
);
}
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
8
,
"
rows
"
:
[{
"
id
"
:
"
A
"
,
"
key
"
:
"
A
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
B
"
,
"
key
"
:
"
B
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
C
"
,
"
key
"
:
"
C
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
D
"
,
"
key
"
:
"
D
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
b
"
,
"
key
"
:
"
b
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
ce
"
,
"
key
"
:
"
ce
"
,
"
value
"
:
{}
},
{
"
id
"
:
"
dee
"
,
"
key
"
:
"
dee
"
,
"
value
"
:
{}
},
{
"
id
"
:
shared
.
created_document_id
,
"
key
"
:
shared
.
created_document_id
,
"
value
"
:
{}
}]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 8 documents from local (4 document + 4 databases)
"
);
}
// function removeCreatedDocuments() {
// return success(RSVP.all([
// jio_index.remove({"_id": shared.created_document_id}),
// jio_index.remove({"_id": "b"}),
// jio_index.remove({"_id": "ce"}),
// 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
"
});
}]);
}
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
listEmptyIndexes
()
{
return
RSVP
.
all
([
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
())
]);
}
function
listEmptyIndexesTest
(
answers
)
{
deepEqual
(
answers
[
0
],
{
"
data
"
:
{
"
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
"
);
}
// // 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"});
// }]);
// }
// 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
{
deepEqual
(
error
,
"
UNEXPECTED ERROR
"
,
"
Unexpected error
"
);
}
}
stop
();
// # Post new documents, list them and remove them
// post a 201
postNewDocument
().
then
(
postNewDocumentTest
).
// get 200
then
(
getCreatedDocument
).
then
(
getCreatedDocumentTest
).
// post b ce dee 201
then
(
postSpecificDocuments
).
then
(
postSpecificDocumentsTest
).
// allD 200 1 documents from index contributor
then
(
listDocumentsFromIndexContributor
).
then
(
listDocumentsFromIndexContributorTest
).
// allD 200 2 documents from index title
then
(
listDocumentsFromIndexTitle
).
then
(
listDocumentsFromIndexTitleTest
).
// allD 200 2 documents from index title year
then
(
listDocumentsFromIndexTitleYear
).
then
(
listDocumentsFromIndexTitleYearTest
).
// allD 200 0 documents from index author
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