Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Aurel
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 @@
...
@@ -17,7 +17,7 @@
*/
*/
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, regexp: true */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, regexp: true */
/*global
jIO, define
, complex_queries */
/*global
window, exports, require, define, jIO, RSVP
, complex_queries */
/**
/**
* JIO Index Storage.
* JIO Index Storage.
...
@@ -118,131 +118,23 @@
...
@@ -118,131 +118,23 @@
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
return
define
(
dependencies
,
module
);
}
}
module
(
jIO
,
complex_queries
);
if
(
typeof
exports
===
'
object
'
)
{
}([
'
jio
'
,
'
complex_queries
'
],
function
(
jIO
,
complex_queries
)
{
return
module
(
"
use strict
"
;
exports
,
require
(
'
jio
'
),
var
error_dict
=
{
require
(
'
rsvp
'
),
"
Corrupted Index
"
:
{
require
(
'
complex_queries
'
)
"
status
"
:
24
,
);
"
statusText
"
:
"
Corrupt
"
,
"
error
"
:
"
corrupt
"
,
"
reason
"
:
"
corrupted index database
"
},
"
Corrupted Metadata
"
:
{
"
status
"
:
24
,
"
statusText
"
:
"
Corrupt
"
,
"
error
"
:
"
corrupt
"
,
"
reason
"
:
"
corrupted document
"
},
"
Not Found
"
:
{
"
status
"
:
404
,
"
statusText
"
:
"
Not Found
"
,
"
error
"
:
"
not_found
"
,
"
reason
"
:
"
missing document
"
},
"
Conflict
"
:
{
"
status
"
:
409
,
"
statusText
"
:
"
Conflicts
"
,
"
error
"
:
"
conflicts
"
,
"
reason
"
:
"
already exist
"
},
"
Different Index
"
:
{
"
status
"
:
40
,
"
statusText
"
:
"
Check failed
"
,
"
error
"
:
"
check_failed
"
,
"
reason
"
:
"
incomplete database
"
}
};
/**
* Generate a JIO Error Object
*
* @method generateErrorObject
* @param {String} name The error name
* @param {String} message The error message
* @param {String} [reason] The error reason
* @return {Object} A jIO error object
*/
function
generateErrorObject
(
name
,
message
,
reason
)
{
if
(
!
error_dict
[
name
])
{
return
{
"
status
"
:
0
,
"
statusText
"
:
"
Unknown
"
,
"
error
"
:
"
unknown
"
,
"
message
"
:
message
,
"
reason
"
:
reason
||
"
unknown
"
};
}
return
{
"
status
"
:
error_dict
[
name
].
status
,
"
statusText
"
:
error_dict
[
name
].
statusText
,
"
error
"
:
error_dict
[
name
].
error
,
"
message
"
:
message
,
"
reason
"
:
reason
||
error_dict
[
name
].
reason
};
}
/**
* Get the real type of an object
* @method type
* @param {Any} value The value to check
* @return {String} The value type
*/
function
type
(
value
)
{
// returns "String", "Object", "Array", "RegExp", ...
return
(
/^
\[
object
([
a-zA-Z
]
+
)\]
$/
).
exec
(
Object
.
prototype
.
toString
.
call
(
value
)
)[
1
];
}
/**
* Generate a new uuid
* @method generateUuid
* @return {string} The new uuid
*/
function
generateUuid
()
{
var
S4
=
function
()
{
var
i
,
string
=
Math
.
floor
(
Math
.
random
()
*
0x10000
/* 65536 */
).
toString
(
16
);
for
(
i
=
string
.
length
;
i
<
4
;
i
+=
1
)
{
string
=
"
0
"
+
string
;
}
return
string
;
};
return
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
S4
()
+
S4
();
}
/**
* Tool to get the date in W3C date format "2011-12-13T14:15:16+01:00"
*
* @param {Any} date The new Date() parameter
* @return {String} The date in W3C date format
*/
function
w3cDate
(
date
)
{
var
d
=
new
Date
(
date
),
offset
=
-
d
.
getTimezoneOffset
();
return
(
d
.
getFullYear
()
+
"
-
"
+
(
d
.
getMonth
()
+
1
)
+
"
-
"
+
d
.
getDate
()
+
"
T
"
+
d
.
getHours
()
+
"
:
"
+
d
.
getMinutes
()
+
"
:
"
+
d
.
getSeconds
()
+
(
offset
<
0
?
"
-
"
:
"
+
"
)
+
(
offset
/
60
)
+
"
:
"
+
(
offset
%
60
)
).
replace
(
/
[
0-9
]
+/g
,
function
(
found
)
{
if
(
found
.
length
<
2
)
{
return
'
0
'
+
found
;
}
return
found
;
});
}
}
window
.
index_storage
=
{};
module
(
window
.
index_storage
,
jIO
,
RSVP
,
complex_queries
);
}([
'
exports
'
,
'
jio
'
,
'
rsvp
'
,
'
complex_queries
'
],
function
(
exports
,
jIO
,
RSVP
,
complex_queries
)
{
"
use strict
"
;
/**
/**
* A JSON Index manipulator
* A JSON Index manipulator
...
@@ -314,7 +206,7 @@
...
@@ -314,7 +206,7 @@
*/
*/
that
.
put
=
function
(
meta
)
{
that
.
put
=
function
(
meta
)
{
var
k
,
needed_meta
=
{},
ok
=
false
;
var
k
,
needed_meta
=
{},
ok
=
false
;
if
(
typeof
meta
.
_id
!==
"
string
"
&&
meta
.
_id
!
==
""
)
{
if
(
typeof
meta
.
_id
!==
"
string
"
||
meta
.
_id
=
==
""
)
{
throw
new
TypeError
(
"
Corrupted Metadata
"
);
throw
new
TypeError
(
"
Corrupted Metadata
"
);
}
}
for
(
k
in
meta
)
{
for
(
k
in
meta
)
{
...
@@ -359,7 +251,8 @@
...
@@ -359,7 +251,8 @@
throw
new
TypeError
(
"
Corrupted Metadata
"
);
throw
new
TypeError
(
"
Corrupted Metadata
"
);
}
}
if
(
typeof
that
.
_location
[
meta
.
_id
]
!==
"
number
"
)
{
if
(
typeof
that
.
_location
[
meta
.
_id
]
!==
"
number
"
)
{
throw
new
ReferenceError
(
"
Not Found
"
);
// throw new ReferenceError("Not Found");
return
;
}
}
that
.
_database
[
that
.
_location
[
meta
.
_id
]]
=
null
;
that
.
_database
[
that
.
_location
[
meta
.
_id
]]
=
null
;
that
.
_free
.
push
(
that
.
_location
[
meta
.
_id
]);
that
.
_free
.
push
(
that
.
_location
[
meta
.
_id
]);
...
@@ -388,7 +281,8 @@
...
@@ -388,7 +281,8 @@
for
(
id
in
that
.
_location
)
{
for
(
id
in
that
.
_location
)
{
if
(
that
.
_location
.
hasOwnProperty
(
id
))
{
if
(
that
.
_location
.
hasOwnProperty
(
id
))
{
database_meta
=
that
.
_database
[
that
.
_location
[
id
]];
database_meta
=
that
.
_database
[
that
.
_location
[
id
]];
if
(
type
(
database_meta
)
!==
"
Object
"
||
if
(
typeof
database_meta
!==
'
object
'
||
Object
.
getPrototypeOf
(
database_meta
||
[])
!==
Object
.
prototype
||
database_meta
.
_id
!==
id
)
{
database_meta
.
_id
!==
id
)
{
throw
new
TypeError
(
"
Corrupted Index
"
);
throw
new
TypeError
(
"
Corrupted Index
"
);
}
}
...
@@ -421,8 +315,11 @@
...
@@ -421,8 +315,11 @@
that
.
checkDocument
=
function
(
doc
)
{
that
.
checkDocument
=
function
(
doc
)
{
var
i
,
key
,
db_doc
;
var
i
,
key
,
db_doc
;
if
(
typeof
that
.
_location
[
doc
.
_id
]
!==
"
number
"
||
if
(
typeof
that
.
_location
[
doc
.
_id
]
!==
"
number
"
)
{
(
db_doc
=
that
.
_database
(
that
.
_location
[
doc
.
_id
]).
_id
)
!==
doc
.
_id
)
{
throw
new
TypeError
(
"
Different Index
"
);
}
db_doc
=
that
.
_database
(
that
.
_location
[
doc
.
_id
]).
_id
;
if
(
db_doc
!==
doc
.
_id
)
{
throw
new
TypeError
(
"
Different Index
"
);
throw
new
TypeError
(
"
Different Index
"
);
}
}
for
(
i
=
0
;
i
<
that
.
_indexing
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
that
.
_indexing
.
length
;
i
+=
1
)
{
...
@@ -442,12 +339,13 @@
...
@@ -442,12 +339,13 @@
var
i
=
0
,
meta
;
var
i
=
0
,
meta
;
that
.
_free
=
[];
that
.
_free
=
[];
that
.
_location
=
{};
that
.
_location
=
{};
if
(
type
(
that
.
_database
)
!==
"
Array
"
)
{
if
(
!
Array
.
isArray
(
that
.
_database
)
)
{
that
.
_database
=
[];
that
.
_database
=
[];
}
}
while
(
i
<
that
.
_database
.
length
)
{
while
(
i
<
that
.
_database
.
length
)
{
meta
=
that
.
_database
[
i
];
meta
=
that
.
_database
[
i
];
if
(
type
(
meta
)
===
"
Object
"
&&
if
(
typeof
meta
===
'
object
'
&&
Object
.
getPrototypeOf
(
meta
||
[])
===
Object
.
prototype
&&
typeof
meta
.
_id
===
"
string
"
&&
meta
.
_id
!==
""
&&
typeof
meta
.
_id
===
"
string
"
&&
meta
.
_id
!==
""
&&
!
that
.
_location
[
meta
.
_id
])
{
!
that
.
_location
[
meta
.
_id
])
{
that
.
_location
[
meta
.
_id
]
=
i
;
that
.
_location
[
meta
.
_id
]
=
i
;
...
@@ -461,10 +359,10 @@
...
@@ -461,10 +359,10 @@
/**
/**
* Returns the serialized version of this object (not cloned)
* Returns the serialized version of this object (not cloned)
*
*
* @method
serialized
* @method
toJSON
* @return {Object} The serialized version
* @return {Object} The serialized version
*/
*/
that
.
serialized
=
function
()
{
that
.
toJSON
=
function
()
{
return
{
return
{
"
indexing
"
:
that
.
_indexing
,
"
indexing
"
:
that
.
_indexing
,
"
free
"
:
that
.
_free
,
"
free
"
:
that
.
_free
,
...
@@ -480,46 +378,59 @@
...
@@ -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.
* Return the similarity percentage (1 >= p >= 0) between two index lists.
*
*
* @method similarityPercentage
* @param {Array} list_a An index list
* @param {Array} list_a An index list
* @param {Array} list_b Another index list
* @param {Array} list_b Another index list
* @return {Number} The similarity percentage
* @return {Number} The similarity percentage
*/
*/
priv
.
similarityPercentage
=
function
(
list_a
,
list_b
)
{
function
similarityPercentage
(
list_a
,
list_b
)
{
var
ai
,
bi
,
count
=
0
;
var
ai
,
bi
,
count
=
0
;
for
(
ai
=
0
;
ai
<
list_a
.
length
;
ai
+=
1
)
{
for
(
ai
=
0
;
ai
<
list_a
.
length
;
ai
+=
1
)
{
for
(
bi
=
0
;
bi
<
list_b
.
length
;
bi
+=
1
)
{
for
(
bi
=
0
;
bi
<
list_b
.
length
;
bi
+=
1
)
{
if
(
list_a
[
ai
]
===
list_b
[
bi
])
{
if
(
list_a
[
ai
]
===
list_b
[
bi
])
{
count
+=
1
;
count
+=
1
;
break
;
}
}
}
}
}
}
return
count
/
(
list_a
.
length
>
list_b
.
length
?
return
count
/
(
list_a
.
length
>
list_b
.
length
?
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.
* Select the good index to use according to a select list.
...
@@ -528,11 +439,10 @@
...
@@ -528,11 +439,10 @@
* @param {Array} select_list An array of strings
* @param {Array} select_list An array of strings
* @return {Number} The index index
* @return {Number} The index index
*/
*/
priv
.
selectIndex
=
function
(
select_list
)
{
IndexStorage
.
prototype
.
selectIndex
=
function
(
select_list
)
{
var
i
,
tmp
,
selector
=
{
"
index
"
:
0
,
"
similarity
"
:
0
};
var
i
,
tmp
,
selector
=
{
"
index
"
:
0
,
"
similarity
"
:
0
};
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
tmp
=
priv
.
similarityPercentage
(
select_list
,
tmp
=
similarityPercentage
(
select_list
,
this
.
_indices
[
i
].
index
);
priv
.
indices
[
i
].
index
);
if
(
tmp
>
selector
.
similarity
)
{
if
(
tmp
>
selector
.
similarity
)
{
selector
.
index
=
i
;
selector
.
index
=
i
;
selector
.
similarity
=
tmp
;
selector
.
similarity
=
tmp
;
...
@@ -541,293 +451,233 @@
...
@@ -541,293 +451,233 @@
return
selector
.
index
;
return
selector
.
index
;
};
};
/**
IndexStorage
.
prototype
.
getIndexDatabase
=
function
(
command
,
index
)
{
* Get a database
index
=
this
.
_indices
[
index
];
*
function
makeNewIndex
()
{
* @method getIndexDatabase
return
new
JSONIndex
({
* @param {Object} option The command option
"
_id
"
:
index
.
id
,
* @param {Number} number The location in priv.indices
"
_attachment
"
:
index
.
attachment
||
"
body
"
,
* @param {Function} callback The callback
"
indexing
"
:
index
.
index
*/
});
priv
.
getIndexDatabase
=
function
(
option
,
number
,
callback
)
{
}
that
.
addJob
(
return
command
.
storage
(
"
getAttachment
"
,
index
.
sub_storage
||
this
.
_sub_storage
priv
.
indices
[
number
].
sub_storage
||
priv
.
sub_storage
,
).
getAttachment
({
{
"
_id
"
:
index
.
id
,
"
_id
"
:
priv
.
indices
[
number
].
id
,
"
_attachment
"
:
index
.
attachment
||
"
body
"
"
_attachment
"
:
priv
.
indices
[
number
].
attachment
||
"
body
"
}).
then
(
function
(
response
)
{
},
return
jIO
.
util
.
readBlobAsText
(
response
.
data
);
option
,
}).
then
(
function
(
e
)
{
function
(
response
)
{
try
{
try
{
response
=
JSON
.
parse
(
response
);
e
=
JSON
.
parse
(
e
.
target
.
result
);
response
.
_id
=
priv
.
indices
[
number
].
id
;
e
.
_id
=
index
.
id
;
response
.
_attachment
=
priv
.
indices
[
number
].
attachment
||
"
body
"
;
e
.
_attachment
=
index
.
attachment
||
"
body
"
;
callback
(
new
JSONIndex
(
response
));
}
catch
(
e1
)
{
}
catch
(
e
)
{
return
makeNewIndex
();
return
that
.
error
(
generateErrorObject
(
}
e
.
message
,
return
new
JSONIndex
(
e
);
"
Repair is necessary
"
,
},
function
(
err
)
{
"
corrupt
"
));
}
},
function
(
err
)
{
if
(
err
.
status
===
404
)
{
if
(
err
.
status
===
404
)
{
callback
(
new
JSONIndex
({
return
makeNewIndex
();
"
_id
"
:
priv
.
indices
[
number
].
id
,
// go back to fulfillment channel
"
_attachment
"
:
priv
.
indices
[
number
].
attachment
||
"
body
"
,
"
indexing
"
:
priv
.
indices
[
number
].
index
}));
return
;
}
}
err
.
message
=
"
Unable to get index database.
"
;
throw
err
;
that
.
error
(
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
);
};
};
/**
IndexStorage
.
prototype
.
storeIndexDatabase
=
function
(
command
,
database
,
* Gets a list containing all the databases set in the storage description.
index
)
{
*
var
that
=
this
;
* @method getIndexDatabaseList
index
=
this
.
_indices
[
index
];
* @param {Object} option The command option
function
putAttachment
()
{
* @param {Function} callback The result callback(database_list)
return
command
.
storage
(
*/
index
.
sub_storage
||
that
.
_sub_storage
priv
.
getIndexDatabaseList
=
function
(
option
,
callback
)
{
).
putAttachment
({
var
i
,
count
=
0
,
callbacks
=
{},
response_list
=
[];
"
_id
"
:
index
.
id
,
callbacks
.
error
=
function
(
index
)
{
"
_attachment
"
:
index
.
attachment
||
"
body
"
,
return
function
(
err
)
{
"
_data
"
:
JSON
.
stringify
(
database
),
"
_content_type
"
:
"
application/json
"
});
}
function
createDatabaseAndPutAttachmentIfPossible
(
err
)
{
if
(
err
.
status
===
404
)
{
if
(
err
.
status
===
404
)
{
response_list
[
index
]
=
new
JSONIndex
({
return
command
.
storage
(
"
_id
"
:
priv
.
indices
[
index
].
id
,
index
.
sub_storage
||
that
.
_sub_storage
"
_attachment
"
:
priv
.
indices
[
index
].
attachment
||
"
body
"
,
).
post
({
"
indexing
"
:
priv
.
indices
[
index
].
index
"
_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.
"
;
return
putAttachment
().
that
.
error
(
err
);
then
(
null
,
createDatabaseAndPutAttachmentIfPossible
);
};
};
};
callbacks
.
success
=
function
(
index
)
{
IndexStorage
.
prototype
.
storeIndexDatabases
=
function
(
command
,
databases
)
{
return
function
(
response
)
{
var
i
,
promises
=
[];
try
{
for
(
i
=
0
;
i
<
this
.
_indices
.
length
;
i
+=
1
)
{
response
=
JSON
.
parse
(
response
);
if
(
databases
[
i
]
!==
undefined
)
{
response
.
_id
=
priv
.
indices
[
index
].
id
;
promises
[
promises
.
length
]
=
response
.
_attachment
=
priv
.
indices
[
index
].
attachment
||
"
body
"
;
this
.
storeIndexDatabase
(
command
,
databases
[
i
],
i
);
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
)
);
}
}
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
* @method genericCommand
* @param {Array} database_list The database list
* @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 {Object} option The command option
* @param {Function} callback The result callback(err, response)
*/
*/
priv
.
storeIndexDatabaseList
=
function
(
database_list
,
option
,
callback
)
{
IndexStorage
.
prototype
.
genericCommand
=
function
(
method
,
command
,
var
i
,
count
=
0
,
count_max
=
0
;
metadata
,
option
)
{
function
onAttachmentResponse
(
response
)
{
var
that
=
this
,
generic_response
;
count
+=
1
;
function
updateAndStoreIndexDatabases
(
responses
)
{
if
(
count
===
count_max
)
{
var
i
,
database_list
=
responses
[
0
];
callback
({
"
ok
"
:
true
});
generic_response
=
responses
[
1
];
}
if
(
method
===
'
get
'
)
{
}
jIO
.
util
.
dictUpdate
(
metadata
,
generic_response
.
data
);
function
onAttachmentError
(
err
)
{
}
err
.
message
=
"
Unable to store index database.
"
;
metadata
.
_id
=
generic_response
.
id
;
that
.
error
(
err
);
if
(
method
===
'
remove
'
)
{
}
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
function
putAttachment
(
i
)
{
database_list
[
i
].
remove
(
metadata
);
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
);
}
}
);
}
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
);
}
}
};
/**
function
allProgress
(
progress
)
{
* A generic request method which delegates the request to the sub storage.
if
(
progress
.
index
===
1
)
{
* On response, it will index the document from the request and update all
progress
.
value
.
percentage
*=
0.7
;
// 0 to 70%
* the databases.
command
.
notify
(
progress
.
value
);
*
* @method genericRequest
* @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
;
throw
null
;
// stop propagation
case
"
remove
"
:
for
(
i
=
0
;
i
<
database_list
.
length
;
i
+=
1
)
{
database_list
[
i
].
remove
(
doc
);
}
}
break
;
default
:
function
success
()
{
break
;
command
.
success
(
generic_response
);
}
priv
.
storeIndexDatabaseList
(
database_list
,
option
,
function
()
{
that
.
success
({
"
ok
"
:
true
,
"
id
"
:
doc
.
_id
});
});
});
break
;
default
:
that
.
success
(
response
);
break
;
}
}
},
function
(
err
)
{
function
storeProgress
(
progress
)
{
return
that
.
error
(
err
);
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
* Post the document metadata and update the index
*
* @method post
* @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
)
{
IndexStorage
.
prototype
.
post
=
function
(
command
,
metadata
,
option
)
{
priv
.
genericRequest
(
command
,
'
post
'
);
this
.
genericCommand
(
'
post
'
,
command
,
metadata
,
option
);
};
};
/**
/**
* Update the document metadata and update the index
* Update the document metadata and update the index
*
* @method put
* @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
)
{
IndexStorage
.
prototype
.
put
=
function
(
command
,
metadata
,
option
)
{
priv
.
genericRequest
(
command
,
'
put
'
);
this
.
genericCommand
(
'
put
'
,
command
,
metadata
,
option
);
};
};
/**
/**
* Add an attachment to a document (no index modification)
* Add an attachment to a document (no index modification)
*
* @method putAttachment
* @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
)
{
IndexStorage
.
prototype
.
putAttachment
=
function
(
command
,
param
,
option
)
{
priv
.
genericRequest
(
command
,
'
putAttachment
'
);
command
.
storage
(
this
.
_sub_storage
).
putAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
};
/**
/**
* Get the document metadata
* Get the document metadata
*
* @method get
* @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
)
{
IndexStorage
.
prototype
.
get
=
function
(
command
,
param
,
option
)
{
priv
.
genericRequest
(
command
,
'
get
'
);
this
.
genericCommand
(
'
get
'
,
command
,
param
,
option
);
};
};
/**
/**
* Get the attachment.
* Get the attachment.
*
* @method getAttachment
* @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
)
{
IndexStorage
.
prototype
.
getAttachment
=
function
(
command
,
param
,
option
)
{
priv
.
genericRequest
(
command
,
'
getAttachment
'
);
command
.
storage
(
this
.
_sub_storage
).
getAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
};
/**
/**
* Remove document - removing documents updates index!.
* Remove document - removing documents updates index!.
*
* @method remove
* @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
)
{
IndexStorage
.
prototype
.
remove
=
function
(
command
,
param
,
option
)
{
priv
.
genericRequest
(
command
,
'
remove
'
);
this
.
genericCommand
(
'
remove
'
,
command
,
param
,
option
);
};
};
/**
/**
* Remove attachment
* Remove attachment
*
* @method removeAttachment
* @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
)
{
IndexStorage
.
prototype
.
removeAttachment
=
function
(
command
,
param
,
option
)
{
priv
.
genericRequest
(
command
,
'
removeAttachment
'
);
command
.
storage
(
this
.
_sub_storage
).
removeAttachment
(
param
,
option
).
then
(
command
.
success
,
command
.
error
,
command
.
notify
);
};
};
/**
/**
...
@@ -837,146 +687,172 @@
...
@@ -837,146 +687,172 @@
* @method allDocs
* @method allDocs
* @param {object} command The JIO command
* @param {object} command The JIO command
*/
*/
that
.
allDocs
=
function
(
command
)
{
IndexStorage
.
prototype
.
allDocs
=
function
(
command
,
param
,
option
)
{
// XXX
var
option
=
command
.
cloneOption
(),
/*jslint unparam: true */
index
=
priv
.
selectIndex
(
option
.
select_list
||
[]);
var
index
=
this
.
selectIndex
(
option
.
select_list
||
[]),
delete_id
;
// Include docs option is ignored, if you want to get all the document,
// Include docs option is ignored, if you want to get all the document,
// don't use index storage!
// 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
"
);
option
.
select_list
.
push
(
"
_id
"
);
priv
.
getIndexDatabase
(
option
,
index
,
function
(
db
)
{
delete_id
=
true
;
}
this
.
getIndexDatabase
(
command
,
index
).
then
(
function
(
db
)
{
var
i
,
id
;
var
i
,
id
;
db
=
db
.
_database
;
db
=
db
.
_database
;
complex_queries
.
QueryFactory
.
create
(
option
.
query
||
''
).
complex_queries
.
QueryFactory
.
create
(
option
.
query
||
''
).
exec
(
db
,
option
);
exec
(
db
,
option
);
for
(
i
=
0
;
i
<
db
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
db
.
length
;
i
+=
1
)
{
id
=
db
[
i
].
_id
;
id
=
db
[
i
].
_id
;
if
(
delete_id
)
{
delete
db
[
i
].
_id
;
delete
db
[
i
].
_id
;
}
db
[
i
]
=
{
db
[
i
]
=
{
"
id
"
:
id
,
"
id
"
:
id
,
"
key
"
:
id
,
"
value
"
:
db
[
i
]
"
value
"
:
db
[
i
],
};
}
that
.
success
({
"
total_rows
"
:
db
.
length
,
"
rows
"
:
db
});
});
};
};
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
);
}
}
);
command
.
success
(
200
,
{
"
data
"
:
{
"
total_rows
"
:
db
.
length
,
"
rows
"
:
db
}});
};
},
function
(
err
)
{
if
(
err
.
status
===
404
)
{
priv
.
repairDocument
=
function
(
command
,
just_check
)
{
return
command
.
success
(
200
,
{
"
data
"
:
{
"
total_rows
"
:
0
,
"
rows
"
:
[]}});
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
.
error
(
err
);
});
});
},
function
(
err
)
{
err
.
message
=
"
Unable to repair document
"
;
return
that
.
error
(
err
);
}
);
};
};
that
.
repair
=
function
(
command
,
just_check
)
{
// IndexStorage.prototype.check = function (command, param, option) { // XXX
var
database_index
=
-
1
,
i
;
// this.repair(command, true, param, option);
for
(
i
=
0
;
i
<
priv
.
indices
.
length
;
i
+=
1
)
{
// };
if
(
priv
.
indices
[
i
].
id
===
command
.
getDocId
())
{
database_index
=
i
;
// IndexStorage.prototype.repairIndexDatabase = function (
break
;
// command,
}
// index,
}
// just_check,
that
.
addJob
(
// param,
"
repair
"
,
// option
priv
.
sub_storage
,
// ) { // XXX
command
.
cloneDoc
(),
// var i, that = this;
command
.
cloneOption
(),
// command.storage(this._sub_storage).allDocs({'include_docs': true}).then(
function
(
response
)
{
// function (response) {
if
(
database_index
!==
-
1
)
{
// var db_list = [], db = new JSONIndex({
priv
.
repairIndexDatabase
(
command
,
database_index
,
just_check
);
// "_id": param._id,
}
else
{
// "_attachment": that._indices[index].attachment || "body",
priv
.
repairDocument
(
command
,
just_check
);
// "indexing": that._indices[index].index
}
// });
},
// for (i = 0; i < response.rows.length; i += 1) {
function
(
err
)
{
// db.put(response.rows[i].doc);
err
.
message
=
"
Could not repair sub storage
"
;
// }
that
.
error
(
err
);
// 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 */
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO, jio_tests, test, ok, deepEqual, sinon */
/*global define, module, test_util, RSVP, jIO, local_storage, test, ok,
deepEqual, stop, start */
// define([module_name], [dependencies], module);
// define([module_name], [dependencies], module);
(
function
(
dependencies
,
module
)
{
(
function
(
dependencies
,
module
)
{
...
@@ -7,1108 +8,621 @@
...
@@ -7,1108 +8,621 @@
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
if
(
typeof
define
===
'
function
'
&&
define
.
amd
)
{
return
define
(
dependencies
,
module
);
return
define
(
dependencies
,
module
);
}
}
module
(
jIO
,
jio_tests
);
module
(
test_util
,
RSVP
,
jIO
,
local_storage
);
}([
'
jio
'
,
'
jio_tests
'
,
'
localstorage
'
,
'
indexstorage
'
],
function
(
jIO
,
util
)
{
}([
'
test_util
'
,
'
rsvp
'
,
'
jio
'
,
'
localstorage
'
,
'
indexstorage
'
],
function
(
util
,
RSVP
,
jIO
,
local_storage
)
{
"
use strict
"
;
"
use strict
"
;
function
generateTools
()
{
function
success
(
promise
)
{
return
{
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
,
notify
)
{
clock
:
sinon
.
useFakeTimers
(),
/*jslint unparam: true*/
spy
:
util
.
ospy
,
promise
.
then
(
resolve
,
resolve
,
notify
);
tick
:
util
.
otick
},
function
()
{
};
promise
.
cancel
();
});
}
}
module
(
"
IndexStorage
"
);
/**
* sequence(thens): Promise
test
(
"
Post
"
,
function
()
{
*
* Executes a sequence of *then* callbacks. It acts like
var
o
=
generateTools
();
* `smth().then(callback).then(callback)...`. The first callback is called
* with no parameter.
o
.
jio
=
jIO
.
newJio
({
*
"
type
"
:
"
indexed
"
,
* Elements of `thens` array can be a function or an array contaning at most
"
indices
"
:
[
* three *then* callbacks: *onFulfilled*, *onRejected*, *onNotified*.
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
title
"
]},
*
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
* When `cancel()` is executed, each then promises are cancelled at the same
],
* time.
"
sub_storage
"
:
{
*
"
type
"
:
"
local
"
,
* @param {Array} thens An array of *then* callbacks
"
username
"
:
"
ipost
"
,
* @return {Promise} A new promise
"
application_name
"
:
"
ipost
"
*/
}
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
)
{
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
if
(
Array
.
isArray
(
thens
[
i
]))
{
if
(
response
)
{
promises
[
i
+
1
]
=
promises
[
i
].
try
{
then
(
thens
[
i
][
0
],
thens
[
i
][
1
],
thens
[
i
][
2
]);
response
=
JSON
.
parse
(
response
);
}
else
{
}
catch
(
e
)
{
promises
[
i
+
1
]
=
promises
[
i
].
then
(
thens
[
i
]);
response
=
"
PARSE ERROR
"
+
response
;
}
}
}
}
o
.
f
(
err
,
response
);
promises
[
i
].
then
(
resolve
,
reject
,
notify
);
};
},
function
()
{
var
i
;
// post without id
for
(
i
=
0
;
i
<
promises
.
length
;
i
+=
1
)
{
o
.
spy
(
o
,
"
jobstatus
"
,
"
done
"
,
"
Post without id
"
);
promises
[
i
].
cancel
();
o
.
jio
.
post
({},
function
(
err
,
response
)
{
o
.
id
=
(
response
||
{}).
id
;
o
.
f
(
err
,
response
);
});
o
.
tick
(
o
);
// post non empty document
o
.
doc
=
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
My Title
"
,
"
year
"
:
2000
,
"
hey
"
:
"
def
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
some_id
"
},
"
Post document
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check document
o
.
fakeIndexA
=
{
"
indexing
"
:
[
"
title
"
],
"
free
"
:
[],
"
location
"
:
{
"
some_id
"
:
0
},
"
database
"
:
[
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
My Title
"
}
]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
=
{
"
indexing
"
:
[
"
title
"
,
"
year
"
],
"
free
"
:
[],
"
location
"
:
{
"
some_id
"
:
0
},
"
database
"
:
[
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
My Title
"
,
"
year
"
:
2000
}
]
};
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// post with escapable characters
o
.
doc
=
{
"
_id
"
:
"
other_id
"
,
"
title
"
:
"
myPost2
"
,
"
findMeA
"
:
"
keyword_*§$%&/()=?
"
,
"
findMeB
"
:
"
keyword_|ð@ł¶đæðſæðæſ³
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
other_id
"
},
"
Post with escapable characters
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// post and document already exists
o
.
doc
=
{
"
_id
"
:
"
some_id
"
,
"
title
"
:
"
myPost3
"
,
"
findMeA
"
:
"
keyword_ghi
"
,
"
findMeB
"
:
"
keyword_jkl
"
};
o
.
spy
(
o
,
"
status
"
,
409
,
"
Post and document already exists
"
);
o
.
jio
.
post
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
Put
"
,
function
()
{
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iput
"
,
"
application_name
"
:
"
iput
"
}
}
});
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
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
module
(
"
IndexStorage
"
);
o
.
fakeIndexA
.
location
.
new_doc
=
1
;
o
.
fakeIndexA
.
database
.
push
({
"
_id
"
:
"
new_doc
"
,
"
author
"
:
"
Jane Doe
"
});
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// add second keyword to index file
o
.
doc
=
{
"
_id
"
:
"
put1
"
,
"
title
"
:
"
myPut2
"
,
"
author
"
:
"
Jane Doe
"
,
"
year
"
:
"
1912
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
put1
"
},
"
add second keyword to index file
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check index file
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
fakeIndexB
.
location
.
put1
=
0
;
o
.
fakeIndexB
.
database
.
push
({
"
_id
"
:
"
put1
"
,
"
year
"
:
"
1912
"
});
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
B
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
// remove a keyword from an existing document
o
.
doc
=
{
"
_id
"
:
"
new_doc
"
,
"
title
"
:
"
myPut2
"
};
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
new_doc
"
},
"
Remove keyword from existing document
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
// check index file
delete
o
.
fakeIndexA
.
location
.
new_doc
;
o
.
fakeIndexA
.
database
[
1
]
=
null
;
o
.
fakeIndexA
.
free
.
push
(
1
);
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
util
.
closeAndcleanUpJio
(
o
.
jio
);
});
test
(
"
Check & Repair
"
,
function
()
{
test
(
"
Scenario
"
,
function
()
{
var
o
=
generateTools
(),
i
;
o
.
jio
=
jIO
.
newJio
({
var
LOCAL_STORAGE_SPEC
=
local_storage
.
createDescription
(
'
indexstorage tests
'
,
'
scenario
'
,
'
memory
'
),
INDEX_STORAGE_SPEC
=
{
"
type
"
:
"
indexed
"
,
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
director
"
]},
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
contributor
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
C
"
,
"
index
"
:
[
"
title
"
]},
{
"
id
"
:
"
D
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
],
],
"
sub_storage
"
:
{
"
sub_storage
"
:
LOCAL_STORAGE_SPEC
"
type
"
:
"
local
"
,
},
option
=
{
"
workspace
"
:
{}},
shared
=
{},
jio_index
,
jio_local
;
"
username
"
:
"
indexstoragerepair
"
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
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
=
{
jio_index
=
jIO
.
createJIO
(
INDEX_STORAGE_SPEC
,
option
);
"
indexing
"
:
[
"
director
"
],
jio_local
=
jIO
.
createJIO
(
LOCAL_STORAGE_SPEC
,
option
);
"
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
;
function
postNewDocument
()
{
o
.
fakeIndexA
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
"
id
"
+
i
,
"
director
"
:
"
D
"
+
i
};
return
jio_index
.
post
({
"
title
"
:
"
Unique ID
"
});
o
.
tmp
=
o
.
fakeIndexB
.
free
.
pop
()
||
o
.
fakeIndexB
.
database
.
length
;
o
.
fakeIndexB
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
"
id
"
+
i
,
"
year
"
:
i
};
}
}
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
({
function
postNewDocumentTest
(
answer
)
{
"
type
"
:
"
indexed
"
,
var
uuid
=
answer
.
id
;
"
indices
"
:
[
answer
.
id
=
"
<uuid>
"
;
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
deepEqual
(
answer
,
{
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
"
id
"
:
"
<uuid>
"
,
],
"
method
"
:
"
post
"
,
"
sub_storage
"
:
{
"
result
"
:
"
success
"
,
"
type
"
:
"
local
"
,
"
status
"
:
201
,
"
username
"
:
"
iputatt
"
,
"
statusText
"
:
"
Created
"
"
application_name
"
:
"
iputatt
"
},
"
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
function
getCreatedDocument
()
{
o
.
doc
=
{
"
_id
"
:
"
putattmt1
"
,
"
title
"
:
"
myPutAttmt1
"
};
return
jio_index
.
get
({
"
_id
"
:
shared
.
created_document_id
});
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
putattmt1
"
},
"
Put underlying document
"
);
o
.
jio
.
put
(
o
.
doc
,
o
.
f
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
{
"
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
"
}
}
}
},
"
Check document
"
);
// check attachment
function
getCreatedDocumentTest
(
answer
)
{
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
deepEqual
(
answer
,
{
"
jio/localstorage/iputatt/iputatt/putattmt1/putattmt2
"
"
data
"
:
{
),
""
,
"
Check attachment
"
);
"
_id
"
:
shared
.
created_document_id
,
"
title
"
:
"
Unique ID
"
// update attachment
},
o
.
spy
(
o
,
"
value
"
,
"
id
"
:
shared
.
created_document_id
,
{
"
ok
"
:
true
,
"
id
"
:
"
putattmt1
"
,
"
attachment
"
:
"
putattmt2
"
},
"
method
"
:
"
get
"
,
"
Update Attachment, with data
"
);
"
result
"
:
"
success
"
,
o
.
jio
.
putAttachment
({
"
status
"
:
200
,
"
_id
"
:
"
putattmt1
"
,
"
statusText
"
:
"
Ok
"
"
_attachment
"
:
"
putattmt2
"
,
},
"
Get new document
"
);
"
_data
"
:
"
abc
"
}
},
o
.
f
);
o
.
tick
(
o
);
// function postSpecificDocuments() {
// return success(RSVP.all([
// check document
// jio_index.post({"_id": "b", "title": "Bee", "year": 2013}),
deepEqual
(
util
.
jsonlocalstorage
.
getItem
(
// jio_index.post({"_id": "ce", "contributor": "DCee"}),
"
jio/localstorage/iputatt/iputatt/putattmt1
"
// jio_index.post({"_id": "dee", "format": "text/plain"})
),
{
// ]));
"
_id
"
:
"
putattmt1
"
,
// }
"
title
"
:
"
myPutAttmt1
"
,
"
_attachments
"
:
{
// function postSpecificDocumentsTest(answers) {
"
putattmt2
"
:
{
// deepEqual(answers[0], {
"
length
"
:
3
,
// "id": "b",
// md5("abc")
// "method": "post",
"
digest
"
:
"
md5-900150983cd24fb0d6963f7d28e17f72
"
// "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
()
{
function
listDocumentsFromIndexTitleYear
()
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
year
"
,
"
title
"
]});
// not sure these need to be run, because the index does not change
// and only small modifications have been made to handle putAttachment
// tests are from localStorage putAttachment
var
o
=
generateTools
();
o
.
jio
=
jIO
.
newJio
({
"
type
"
:
"
indexed
"
,
"
indices
"
:
[
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
author
"
]},
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
year
"
]}
],
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
iget
"
,
"
application_name
"
:
"
iget
"
}
}
});
// get inexistent document
function
listDocumentsFromIndexTitleYearTest
(
answer
)
{
o
.
spy
(
o
,
"
status
"
,
404
,
"
Get inexistent document
"
);
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
o
.
jio
.
get
({
"
_id
"
:
"
get1
"
},
o
.
f
);
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
o
.
tick
(
o
);
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
// 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
);
);
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
function
listDocumentsFromIndexTitle
()
{
o
.
spy
(
o
,
"
status
"
,
404
,
"
Remove inexistent document
"
);
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
title
"
]});
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
function
listDocumentsFromIndexTitleTest
(
answer
)
{
o
.
jio
.
put
({
"
_id
"
:
"
removeAlso
"
,
"
title
"
:
"
myRemove2
"
,
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
"
author
"
:
"
Martin Mustermann
"
,
"
year
"
:
"
2525
"
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
);
}
deepEqual
(
answer
,
{
// remove document
"
data
"
:
{
o
.
spy
(
o
,
"
value
"
,
{
"
ok
"
:
true
,
"
id
"
:
"
remove1
"
},
"
Remove document
"
);
"
total_rows
"
:
2
,
o
.
jio
.
remove
({
"
_id
"
:
"
remove1
"
},
o
.
f
);
"
rows
"
:
[{
o
.
tick
(
o
);
"
id
"
:
"
b
"
,
"
value
"
:
{
"
title
"
:
"
Bee
"
}
// check index
},
{
o
.
fakeIndexA
=
{
"
id
"
:
shared
.
created_document_id
,
"
indexing
"
:
[
"
author
"
],
"
value
"
:
{
"
title
"
:
"
Unique ID
"
}
"
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
"
}]
"
method
"
:
"
allDocs
"
,
};
"
result
"
:
"
success
"
,
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
"
status
"
:
200
,
o
.
jio
.
getAttachment
({
"
statusText
"
:
"
Ok
"
"
_id
"
:
"
B
"
,
},
"
List 2 documents from 'title'
"
);
"
_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
"
}
}
});
o
.
getAttachmentCallback
=
function
(
err
,
response
)
{
function
listDocumentsFromIndexAuthor
()
{
if
(
response
)
{
return
jio_index
.
allDocs
({
"
select_list
"
:
[
"
author
"
]});
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
e
)
{
response
=
"
PARSE ERROR
"
+
response
;
}
}
}
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
({
function
listDocumentsFromIndexAuthorTest
(
answer
)
{
"
type
"
:
"
indexed
"
,
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
"
indices
"
:
[
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
{
"
id
"
:
"
A
"
,
"
index
"
:
[
"
director
"
]},
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
{
"
id
"
:
"
B
"
,
"
index
"
:
[
"
title
"
,
"
year
"
]}
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
],
);
"
sub_storage
"
:
{
"
type
"
:
"
local
"
,
"
username
"
:
"
icomplex
"
,
"
application_name
"
:
"
acomplex
"
}
});
});
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
;
function
listDocumentsFromNothing
()
{
o
.
fakeIndexA
.
database
[
o
.
tmp
]
=
{
return
jio_index
.
allDocs
();
"
_id
"
:
i
.
toString
(),
"
director
"
:
o
.
director
[
i
]
};
o
.
fakeIndexA
.
location
[
i
]
=
o
.
tmp
;
o
.
tmp
=
o
.
fakeIndexB
.
free
.
pop
()
||
o
.
fakeIndexB
.
database
.
length
;
o
.
fakeIndexB
.
database
[
o
.
tmp
]
=
{
"
_id
"
:
i
.
toString
(),
"
year
"
:
o
.
years
[
i
],
"
title
"
:
o
.
titles
[
i
]
};
o
.
fakeIndexB
.
location
[
i
]
=
o
.
tmp
;
o
.
clock
.
tick
(
1000
);
}
}
// o.clock.tick(1000);
// check index file
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexA
,
"
Check index file
"
);
o
.
jio
.
getAttachment
({
"
_id
"
:
"
A
"
,
"
_attachment
"
:
"
body
"
},
o
.
getAttachmentCallback
);
o
.
tick
(
o
);
o
.
spy
(
o
,
"
value
"
,
o
.
fakeIndexB
,
"
Check index file
"
);
function
listDocumentsFromNothingTest
(
answer
)
{
o
.
jio
.
getAttachment
({
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
"
_id
"
:
"
B
"
,
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
"
_attachment
"
:
"
body
"
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
},
o
.
getAttachmentCallback
);
a
.
id
.
length
>
b
.
id
.
length
?
1
:
0
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
]
}
});
});
}
}
deepEqual
(
answer
,
{
o
.
response
=
JSON
.
parse
(
JSON
.
stringify
(
o
.
allDocsResponse
));
"
data
"
:
{
for
(
i
=
0
;
i
<
o
.
response
.
rows
.
length
;
i
+=
1
)
{
"
total_rows
"
:
1
,
delete
o
.
response
.
rows
[
i
].
doc
;
"
rows
"
:
[{
"
id
"
:
"
ce
"
,
"
value
"
:
{}
}]
},
"
method
"
:
"
allDocs
"
,
"
result
"
:
"
success
"
,
"
status
"
:
200
,
"
statusText
"
:
"
Ok
"
},
"
List 1 document from first index (`allDocs()`)
"
);
}
}
// alldocs
function
listDocumentsFromLocal
()
{
o
.
spy
(
o
,
"
value
"
,
o
.
response
,
"
AllDocs response generated from index
"
);
return
jio_local
.
allDocs
();
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
;
}
}
}
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
function
listDocumentsFromLocalTest
(
answer
)
{
o
.
spy
(
o
,
"
value
"
,
{
"
total_rows
"
:
0
,
"
rows
"
:
[]},
if
(
answer
&&
answer
.
data
&&
Array
.
isArray
(
answer
.
data
.
rows
))
{
"
allDocs (complex queries year >= 1980, can't use index)
"
);
answer
.
data
.
rows
.
sort
(
function
(
a
,
b
)
{
o
.
jio
.
allDocs
({
return
a
.
id
.
length
<
b
.
id
.
length
?
-
1
:
(
// "query":'(year: >= "1980" AND year: < "2000")',
a
.
id
.
length
>
b
.
id
.
length
?
1
:
(
"
query
"
:
'
(year: >= "1980")
'
,
a
.
id
<
b
.
id
?
-
1
:
a
.
id
>
b
.
id
?
1
:
0
"
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)
"
);
deepEqual
(
answer
,
{
o
.
jio
.
allDocs
({
"
data
"
:
{
"
sort_on
"
:
[[
'
title
'
,
'
descending
'
]],
"
total_rows
"
:
8
,
"
select_list
"
:
[
'
title
'
]
"
rows
"
:
[{
},
o
.
f
);
"
id
"
:
"
A
"
,
o
.
tick
(
o
);
"
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