Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio-main
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
Hardik Juneja
jio-main
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 @@
*/
/*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
,
...
...
@@ -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
)
{
var
that
,
priv
=
{};
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
);
}
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
()
{
return
{
"
indices
"
:
priv
.
indices
,
"
sub_storage
"
:
priv
.
sub_storage
};
};
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
);
};
/**
* 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
)
{
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
;
}
}
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
)
{
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
?
list_a
.
length
:
list_b
.
length
);
};
throw
err
;
}
return
putAttachment
().
then
(
null
,
createDatabaseAndPutAttachmentIfPossible
);
};
/**
* 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
*/
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
;
}
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
);
}
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.
*
* @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
)
{
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
});
count
+=
1
;
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
)
);
/**
* Generic method for 'post', 'put', 'get' and 'remove'. It delegates the
* command to the sub storage and update the databases.
*
* @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
*/
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
);
}
};
/**
* Saves all the databases to the remote(s).
*
* @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
});
metadata
.
_id
=
generic_response
.
id
;
if
(
method
===
'
remove
'
)
{
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
remove
(
metadata
);
}
}
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
);
}
);
}
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
if
(
database_list
[
i
]
!==
undefined
)
{
count_max
+=
1
;
post
(
i
);
}
else
{
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
put
(
metadata
);
}
}
};
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
);
}
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
allProgress
(
progress
)
{
if
(
progress
.
index
===
1
)
{
progress
.
value
.
percentage
*=
0.7
;
// 0 to 70%
command
.
notify
(
progress
.
value
);
}
throw
null
;
// stop propagation
}
/**
* Post the document metadata and update the index
* @method post
* @param {object} command The JIO command
*/
that
.
post
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
post
'
);
};
function
success
()
{
command
.
success
(
generic_response
);
}
/**
* Update the document metadata and update the index
* @method put
* @param {object} command The JIO command
*/
that
.
put
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
put
'
);
};
function
storeProgress
(
progress
)
{
progress
.
percentage
=
(
0.3
*
progress
.
percentage
)
+
70
;
// 70 to 100%
command
.
notify
(
progress
);
}
/**
* Add an attachment to a document (no index modification)
* @method putAttachment
* @param {object} command The JIO command
*/
that
.
putAttachment
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
putAttachment
'
);
};
RSVP
.
all
([
this
.
getIndexDatabases
(
command
),
command
.
storage
(
this
.
_sub_storage
)[
method
](
metadata
,
option
)
]).
then
(
updateAndStoreIndexDatabases
,
null
,
allProgress
).
then
(
success
,
command
.
error
,
storeProgress
);
};
/**
* Get the document metadata
* @method get
* @param {object} command The JIO command
*/
that
.
get
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
get
'
);
};
/**
* Post the document metadata and update the index
*
* @method post
* @param {Object} command The JIO command
* @param {Object} metadata The metadata to post
* @param {Object} option The command option
*/
IndexStorage
.
prototype
.
post
=
function
(
command
,
metadata
,
option
)
{
this
.
genericCommand
(
'
post
'
,
command
,
metadata
,
option
);
};
/**
* Get the attachment.
* @method getAttachment
* @param {object} command The JIO command
*/
that
.
getAttachment
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
getAttachment
'
);
};
/**
* Update the document metadata and update the index
*
* @method put
* @param {Object} command The JIO command
* @param {Object} metadata The metadata to put
* @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!.
* @method remove
* @param {object} command The JIO command
*/
that
.
remove
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
remove
'
);
};
/**
* Add an attachment to a document (no index modification)
*
* @method putAttachment
* @param {Object} command The JIO command
* @param {Object} param The command parameters
* @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
* @method removeAttachment
* @param {object} command The JIO command
*/
that
.
removeAttachment
=
function
(
command
)
{
priv
.
genericRequest
(
command
,
'
removeAttachment
'
);
};
/**
* Get the document metadata
*
* @method get
* @param {Object} command The JIO command
* @param {Object} param The command parameters
* @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
* Options:
* - {boolean} include_docs Also retrieve the actual document content.
* @method allDocs
* @param {object} command The JIO command
*/
that
.
allDocs
=
function
(
command
)
{
var
option
=
command
.
cloneOption
(),
index
=
priv
.
selectIndex
(
option
.
select_list
||
[]);
// Include docs option is ignored, if you want to get all the document,
// don't use index storage!
/**
* Get the attachment.
*
* @method getAttachment
* @param {Object} command The JIO command
* @param {Object} param The command parameters
* @param {Object} option The command option
*/
IndexStorage
.
prototype
.
getAttachment
=
function
(
command
,
param
,
option
)
{
command
.
storage
(
this
.
_sub_storage
).
getAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
option
.
select_list
=
option
.
select_list
||
[];
option
.
select_list
.
push
(
"
_id
"
);
priv
.
getIndexDatabase
(
option
,
index
,
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
;
delete
db
[
i
].
_id
;
db
[
i
]
=
{
"
id
"
:
id
,
"
key
"
:
id
,
"
value
"
:
db
[
i
],
};
}
that
.
success
({
"
total_rows
"
:
db
.
length
,
"
rows
"
:
db
});
});
};
/**
* Remove document - removing documents updates index!.
*
* @method remove
* @param {Object} command The JIO command
* @param {Object} param The command parameters
* @param {Object} option The command option
*/
IndexStorage
.
prototype
.
remove
=
function
(
command
,
param
,
option
)
{
this
.
genericCommand
(
'
remove
'
,
command
,
param
,
option
);
};
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
();
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
);
}
);
};
/**
* Gets a document list from the substorage
* Options:
* - {boolean} include_docs Also retrieve the actual document content.
* @method allDocs
* @param {object} command The JIO command
*/
IndexStorage
.
prototype
.
allDocs
=
function
(
command
,
param
,
option
)
{
// XXX
/*jslint unparam: true */
var
index
=
this
.
selectIndex
(
option
.
select_list
||
[]),
delete_id
;
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
()});
});
}
});
},
function
(
err
)
{
err
.
message
=
"
Unable to repair document
"
;
return
that
.
error
(
err
);
}
);
};
// Include docs option is ignored, if you want to get all the document,
// don't use index storage!
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
;
option
.
select_list
=
(
Array
.
isArray
(
option
.
select_list
)
?
option
.
select_list
:
[]
);
if
(
option
.
select_list
.
indexOf
(
"
_id
"
)
===
-
1
)
{
option
.
select_list
.
push
(
"
_id
"
);
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
(
"
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
);
}
);
};
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
);
});
};
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 */
/*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
};
}
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
"
}
function
success
(
promise
)
{
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
,
notify
)
{
/*jslint unparam: true*/
promise
.
then
(
resolve
,
resolve
,
notify
);
},
function
()
{
promise
.
cancel
();
});
}
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
/**
* 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
();
});
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
"
}
});
"
sub_storage
"
:
LOCAL_STORAGE_SPEC
},
option
=
{
"
workspace
"
:
{}},
shared
=
{},
jio_index
,
jio_local
;
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
);
};
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
};
jio_index
=
jIO
.
createJIO
(
INDEX_STORAGE_SPEC
,
option
);
jio_local
=
jIO
.
createJIO
(
LOCAL_STORAGE_SPEC
,
option
);
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
"
}
});
// 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
);
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 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
);
function
getCreatedDocument
()
{
return
jio_index
.
get
({
"
_id
"
:
shared
.
created_document_id
});
}
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
);
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
"
);
}
// check document
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
jio/localstorage/iputatt/iputatt/putattmt1
"
),
{
"
_id
"
:
"
putattmt1
"
,
"
title
"
:
"
myPutAttmt1
"
,
"
_attachments
"
:
{
"
putattmt2
"
:
{
"
length
"
:
0
,
// md5("")
"
digest
"
:
"
md5-d41d8cd98f00b204e9800998ecf8427e
"
}
}
},
"
Check 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
"
});
}]);
}
// check attachment
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
jio/localstorage/iputatt/iputatt/putattmt1/putattmt2
"
),
""
,
"
Check attachment
"
);
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)
"
);
}
// 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
);
function
listDocumentsFromIndexContributor
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
contributor
"
]});
}
// 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
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
);
});
}
},
"
Check document
"
);
// check attachment
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
"
jio/localstorage/iputatt/iputatt/putattmt1/putattmt2
"
),
"
abc
"
,
"
Check attachment
"
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
Get
"
,
function
()
{
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'
"
);
}
// 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
();
function
listDocumentsFromIndexTitleYear
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
year
"
,
"
title
"
]});
}
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
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
);
});
}
});
// 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
);
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'
"
);
}
// 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
);
function
listDocumentsFromIndexTitle
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
title
"
]});
}
// adding an attachment
o
.
doc_get1
.
_attachments
=
{
"
get2
"
:
{
"
length
"
:
2
,
// md5("de")
"
digest
"
:
"
md5-5f02f0889301fd7be1ac972c11bf3e7d
"
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
);
});
}
};
util
.
jsonlocalstorage
.
setItem
(
"
jio/localstorage/iget/iget/get1
"
,
o
.
doc_get1
);
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
();
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
2
,
"
rows
"
:
[{
"
id
"
:
"
b
"
,
"
value
"
:
{
"
title
"
:
"
Bee
"
}
},
{
"
id
"
:
shared
.
created_document_id
,
"
value
"
:
{
"
title
"
:
"
Unique ID
"
}
}]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 2 documents from 'title'
"
);
}
o
.
jio
=
jIO
.
newJio
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
irem
"
,
"
application_name
"
:
"
irem
"
}
});
function
listDocumentsFromIndexAuthor
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
author
"
]});
}
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
re
sponse
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
function
listDocumentsFromIndexAuthorTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
)
)
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
re
turn
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
)
;
}
);
}
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
);
// 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
();
deepEqual
(
answer
,
{
"
data
"
:
{
"
total_rows
"
:
0
,
"
rows
"
:
[]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 0 document from 'author'
"
);
}
o
.
jio
=
jIO
.
newJio
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iall
"
,
"
application_name
"
:
"
iall
"
}
});
function
listDocumentsFromNothing
()
{
return
jio_index
.
allDocs
();
}
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
re
sponse
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
function
listDocumentsFromNothingTest
(
answer
)
{
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
)
)
{
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
re
turn
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
)
;
}
);
}
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
;
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()`)
"
);
}
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
"
}
});
o
.
localpath
=
"
jio/localstorage/icomplex/acomplex
"
;
function
listDocumentsFromLocal
()
{
return
jio_local
.
allDocs
();
}
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
response
)
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
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
.
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
);
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)
"
);
}
// 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
);
// 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
"
});
}]);
}
// 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
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)
"
);
}
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
for
(
i
=
0
;
i
<
o
.
response
.
rows
.
length
;
i
+=
1
)
{
delete
o
.
response
.
rows
[
i
].
doc
;
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
())
]);
}
// alldocs
o
.
spy
(
o
,
"
value
"
,
o
.
response
,
"
AllDocs response generated from index
"
);
o
.
jio
.
allDocs
(
o
.
f
);
o
.
tick
(
o
,
1000
);
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
"
);
}
// 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
);
// // 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
{
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
;
deepEqual
(
error
,
"
UNEXPECTED ERROR
"
,
"
Unexpected error
"
);
}
}
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
);
});
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
);
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