Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Bryan Kaperick
jio
Commits
c6db8c50
Commit
c6db8c50
authored
Jun 27, 2018
by
Bryan Kaperick
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made changes to simplify buildQuery revision queries allowing any property names possible.
parent
4306f29f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
632 additions
and
346 deletions
+632
-346
src/jio.storage/historystorage.js
src/jio.storage/historystorage.js
+179
-168
test/jio.storage/historystorage.tests.js
test/jio.storage/historystorage.tests.js
+453
-178
No files found.
src/jio.storage/historystorage.js
View file @
c6db8c50
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
"
use strict
"
;
"
use strict
"
;
// Used to distinguish between operations done within the same millisecond
// Used to distinguish between operations done within the same millisecond
var
unique_timestamp
=
function
(
time
)
{
function
generateUniqueTimestamp
(
time
)
{
// XXX: replace this with UUIDStorage function call to S4() when it becomes
// XXX: replace this with UUIDStorage function call to S4() when it becomes
// publicly accessible
// publicly accessible
...
@@ -13,15 +13,28 @@
...
@@ -13,15 +13,28 @@
//timestamp = Date.now().toString();
//timestamp = Date.now().toString();
timestamp
=
time
.
toString
();
timestamp
=
time
.
toString
();
return
timestamp
+
"
-
"
+
uuid
;
return
timestamp
+
"
-
"
+
uuid
;
}
,
}
looks_like_timestamp
=
function
(
id
)
{
//1529928772623-02e6
function
isTimestamp
(
id
)
{
//A timestamp is of the form
//A timestamp is of the form
//"[13 digit number]-[4 numbers/lowercase letters]"
//"[13 digit number]-[4 numbers/lowercase letters]"
var
re
=
/^
[
0-9
]{13}
-
[
a-z0-9
]{4}
$/
;
var
re
=
/^
[
0-9
]{13}
-
[
a-z0-9
]{4}
$/
;
return
re
.
test
(
id
);
return
re
.
test
(
id
);
};
}
function
throwCantFindError
(
id
)
{
throw
new
jIO
.
util
.
jIOError
(
"
HistoryStorage: cannot find object '
"
+
id
+
"
'
"
,
404
);
}
function
throwRemovedError
(
id
)
{
throw
new
jIO
.
util
.
jIOError
(
"
HistoryStorage: cannot find object '
"
+
id
+
"
' (removed)
"
,
404
);
}
/**
/**
* The jIO HistoryStorage extension
* The jIO HistoryStorage extension
...
@@ -31,11 +44,28 @@
...
@@ -31,11 +44,28 @@
*/
*/
function
HistoryStorage
(
spec
)
{
function
HistoryStorage
(
spec
)
{
this
.
_sub_storage
=
jIO
.
createJIO
(
spec
.
sub_storage
);
this
.
_sub_storage
=
jIO
.
createJIO
(
spec
.
sub_storage
);
this
.
_timestamps
=
{};
}
}
HistoryStorage
.
prototype
.
get
=
function
(
id_in
)
{
HistoryStorage
.
prototype
.
get
=
function
(
id_in
)
{
if
(
isTimestamp
(
id_in
))
{
// Try to treat id_in as a timestamp instead of a name
return
this
.
_sub_storage
.
get
(
id_in
)
.
push
(
function
(
result
)
{
if
(
result
.
op
===
"
put
"
)
{
return
result
.
doc
;
}
throwCantFindError
(
id_in
);
},
function
(
error
)
{
if
(
error
.
status_code
===
404
&&
error
instanceof
jIO
.
util
.
jIOError
)
{
throwRemovedError
(
id_in
);
}
throw
error
;
});
}
// Query to get the last edit made to this document
// Query to get the last edit made to this document
var
substorage
=
this
.
_sub_storage
,
var
substorage
=
this
.
_sub_storage
,
...
@@ -66,65 +96,23 @@
...
@@ -66,65 +96,23 @@
return
substorage
.
get
(
results
.
data
.
rows
[
0
].
id
)
return
substorage
.
get
(
results
.
data
.
rows
[
0
].
id
)
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
return
result
.
doc
;
return
result
.
doc
;
},
function
(
error
)
{
if
(
error
.
status_code
===
400
&&
error
instanceof
jIO
.
util
.
jIOError
)
{
throw
new
jIO
.
util
.
jIOError
(
"
HistoryStorage: cannot find object '
"
+
id_in
+
"
'
"
,
404
);
}
});
});
}
}
throw
new
jIO
.
util
.
jIOError
(
throwRemovedError
(
id_in
);
"
HistoryStorage: cannot find object '
"
+
id_in
+
"
' (removed)
"
,
404
);
}
// Try again by treating id_in as a timestamp instead of a name
return
substorage
.
get
(
id_in
)
.
push
(
function
(
result
)
{
if
(
result
.
op
===
"
put
"
)
{
return
result
.
doc
;
}
throw
new
jIO
.
util
.
jIOError
(
"
HistoryStorage: cannot find object '
"
+
id_in
+
"
' (removed)
"
,
404
);
},
function
(
error
)
{
if
(
error
.
status_code
===
400
&&
error
instanceof
jIO
.
util
.
jIOError
)
{
throw
new
jIO
.
util
.
jIOError
(
"
HistoryStorage: cannot find object '
"
+
id_in
+
"
'
"
,
404
);
}
}
}
);
throwCantFindError
(
id_in
);
});
});
};
};
HistoryStorage
.
prototype
.
put
=
function
(
id
,
data
)
{
HistoryStorage
.
prototype
.
put
=
function
(
id
,
data
)
{
if
(
data
.
hasOwnProperty
(
"
_timestamp
"
))
{
throw
new
jIO
.
util
.
jIOError
(
if
(
isTimestamp
(
id
))
{
"
Document cannot have metadata attribute '_timestamp'
"
,
422
);
}
if
(
data
.
hasOwnProperty
(
"
_doc_id
"
))
{
throw
new
jIO
.
util
.
jIOError
(
"
Document cannot have metadata attribute '_doc_id'
"
,
422
);
}
if
(
looks_like_timestamp
(
id
))
{
throw
new
jIO
.
util
.
jIOError
(
throw
new
jIO
.
util
.
jIOError
(
"
Document cannot have id of the same form as a timestamp
"
,
"
Document cannot have id of the same form as a timestamp
"
,
422
422
);
);
}
}
var
timestamp
=
unique_t
imestamp
(
Date
.
now
()),
var
timestamp
=
generateUniqueT
imestamp
(
Date
.
now
()),
metadata
=
{
metadata
=
{
// XXX: remove this attribute once query can sort_on id
// XXX: remove this attribute once query can sort_on id
timestamp
:
timestamp
,
timestamp
:
timestamp
,
...
@@ -132,37 +120,58 @@
...
@@ -132,37 +120,58 @@
doc
:
data
,
doc
:
data
,
op
:
"
put
"
op
:
"
put
"
};
};
if
(
this
.
_timestamps
.
hasOwnProperty
(
id
))
{
this
.
_timestamps
[
id
].
push
(
timestamp
);
}
else
{
this
.
_timestamps
[
id
]
=
[
timestamp
];
}
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
);
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
);
};
};
HistoryStorage
.
prototype
.
remove
=
function
(
id
)
{
HistoryStorage
.
prototype
.
remove
=
function
(
id
)
{
var
timestamp
=
unique_t
imestamp
(
Date
.
now
()
-
1
),
var
timestamp
=
generateUniqueT
imestamp
(
Date
.
now
()
-
1
),
metadata
=
{
metadata
=
{
// XXX: remove this attribute once query can sort_on id
// XXX: remove this attribute once query can sort_on id
timestamp
:
timestamp
,
timestamp
:
timestamp
,
doc_id
:
id
,
doc_id
:
id
,
op
:
"
remove
"
op
:
"
remove
"
};
};
this
.
_timestamps
[
id
].
push
(
timestamp
);
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
);
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
);
};
};
HistoryStorage
.
prototype
.
allAttachments
=
function
(
id
)
{
HistoryStorage
.
prototype
.
allAttachments
=
function
(
id
)
{
// XXX: If instead you passed a timestamp in as `id`, we could retrieve all
// XXX: allAttachments with timestamp:
// the attachments of the document at that point in time. Not sure if this
// should return all non-removed attachments at this point in time
// would be useful.
var
substorage
=
this
.
_sub_storage
,
var
substorage
=
this
.
_sub_storage
,
// Include id as value in query object for safety (as opposed to string
query_obj
,
// concatenation)
query_removed_check
,
options
,
query_doc_id
,
options_remcheck
;
if
(
isTimestamp
(
id
))
{
query_doc_id
=
new
SimpleQuery
({
operator
:
"
<=
"
,
key
:
"
timestamp
"
,
value
:
id
});
}
else
{
query_doc_id
=
new
SimpleQuery
({
key
:
"
doc_id
"
,
value
:
id
});
}
query_removed_check
=
new
ComplexQuery
({
operator
:
"
AND
"
,
query_list
:
[
query_doc_id
,
new
ComplexQuery
({
operator
:
"
OR
"
,
query_list
:
[
new
SimpleQuery
({
key
:
"
op
"
,
value
:
"
put
"
}),
new
SimpleQuery
({
key
:
"
op
"
,
value
:
"
remove
"
})
]
})
]
});
query_obj
=
new
ComplexQuery
({
query_obj
=
new
ComplexQuery
({
operator
:
"
AND
"
,
operator
:
"
AND
"
,
query_list
:
[
query_list
:
[
new
SimpleQuery
({
key
:
"
doc_id
"
,
value
:
id
})
,
query_doc_id
,
new
ComplexQuery
({
new
ComplexQuery
({
operator
:
"
OR
"
,
operator
:
"
OR
"
,
query_list
:
[
query_list
:
[
...
@@ -171,21 +180,42 @@
...
@@ -171,21 +180,42 @@
]
]
})
})
]
]
}),
});
// Only query for attachment edits
options_remcheck
=
{
query
:
query_removed_check
,
select_list
:
[
"
op
"
,
"
timestamp
"
],
//limit: [0, 1],
sort_on
:
[[
"
timestamp
"
,
"
descending
"
]]
};
options
=
{
options
=
{
query
:
query_obj
,
query
:
query_obj
,
sort_on
:
[[
"
timestamp
"
,
"
descending
"
]],
sort_on
:
[[
"
timestamp
"
,
"
descending
"
]],
select_list
:
[
"
op
"
,
"
timestam
p
"
,
"
name
"
]
select_list
:
[
"
o
p
"
,
"
name
"
]
};
};
return
this
.
_sub_storage
.
allDocs
(
options
)
return
this
.
_sub_storage
.
allDocs
(
options_remcheck
)
.
push
(
function
(
results
)
{
if
(
results
.
data
.
total_rows
>
0
)
{
if
(
results
.
data
.
rows
[
0
].
value
.
op
===
"
remove
"
)
{
throwRemovedError
(
id
);
}
}
else
{
throwCantFindError
(
id
);
}
})
.
push
(
function
()
{
return
substorage
.
allDocs
(
options
);
})
.
push
(
function
(
results
)
{
.
push
(
function
(
results
)
{
var
seen
=
{},
var
seen
=
{},
attachments
=
[],
attachments
=
[],
attachment_promises
=
[],
attachment_promises
=
[],
ind
,
ind
,
entry
;
entry
;
// Only return attachments if:
// (it is the most recent revision) AND (it is a putAttachment)
attachments
=
results
.
data
.
rows
.
filter
(
function
(
docum
)
{
attachments
=
results
.
data
.
rows
.
filter
(
function
(
docum
)
{
if
(
!
seen
.
hasOwnProperty
(
docum
.
value
.
name
))
{
if
(
!
seen
.
hasOwnProperty
(
docum
.
value
.
name
))
{
var
output
=
(
docum
.
value
.
op
===
"
putAttachment
"
);
var
output
=
(
docum
.
value
.
op
===
"
putAttachment
"
);
...
@@ -193,17 +223,19 @@
...
@@ -193,17 +223,19 @@
return
output
;
return
output
;
}
}
});
});
// Assembles object of attachment_name: attachment_object
for
(
ind
=
0
;
ind
<
attachments
.
length
;
ind
+=
1
)
{
for
(
ind
=
0
;
ind
<
attachments
.
length
;
ind
+=
1
)
{
entry
=
attachments
[
ind
];
entry
=
attachments
[
ind
];
attachment_promises
[
entry
.
value
.
name
]
=
attachment_promises
[
entry
.
value
.
name
]
=
substorage
.
getAttachment
(
entry
.
id
,
entry
.
value
.
name
);
substorage
.
getAttachment
(
entry
.
id
,
entry
.
value
.
name
);
}
}
return
RSVP
.
hash
(
attachment_promises
);
return
RSVP
.
hash
(
attachment_promises
);
});
});
};
};
HistoryStorage
.
prototype
.
putAttachment
=
function
(
id
,
name
,
blob
)
{
HistoryStorage
.
prototype
.
putAttachment
=
function
(
id
,
name
,
blob
)
{
var
timestamp
=
unique_t
imestamp
(
Date
.
now
()),
var
timestamp
=
generateUniqueT
imestamp
(
Date
.
now
()),
metadata
=
{
metadata
=
{
// XXX: remove this attribute once query can sort_on id
// XXX: remove this attribute once query can sort_on id
timestamp
:
timestamp
,
timestamp
:
timestamp
,
...
@@ -212,11 +244,6 @@
...
@@ -212,11 +244,6 @@
op
:
"
putAttachment
"
op
:
"
putAttachment
"
},
},
substorage
=
this
.
_sub_storage
;
substorage
=
this
.
_sub_storage
;
if
(
this
.
_timestamps
[
id
].
hasOwnProperty
(
name
))
{
this
.
_timestamps
[
id
][
name
].
push
(
timestamp
);
}
else
{
this
.
_timestamps
[
id
][
name
]
=
[
timestamp
];
}
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
)
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
)
.
push
(
function
()
{
.
push
(
function
()
{
return
substorage
.
putAttachment
(
timestamp
,
name
,
blob
);
return
substorage
.
putAttachment
(
timestamp
,
name
,
blob
);
...
@@ -225,6 +252,17 @@
...
@@ -225,6 +252,17 @@
HistoryStorage
.
prototype
.
getAttachment
=
function
(
id
,
name
)
{
HistoryStorage
.
prototype
.
getAttachment
=
function
(
id
,
name
)
{
if
(
isTimestamp
(
id
))
{
return
this
.
_sub_storage
.
getAttachment
(
id
,
name
)
.
push
(
undefined
,
function
(
error
)
{
if
(
error
.
status_code
===
404
&&
error
instanceof
jIO
.
util
.
jIOError
)
{
throwCantFindError
(
id
);
}
throw
error
;
});
}
// Query to get the last edit made to this document
// Query to get the last edit made to this document
var
substorage
=
this
.
_sub_storage
,
var
substorage
=
this
.
_sub_storage
,
...
@@ -268,39 +306,16 @@
...
@@ -268,39 +306,16 @@
if
(
results
.
data
.
rows
.
length
>
0
)
{
if
(
results
.
data
.
rows
.
length
>
0
)
{
if
(
results
.
data
.
rows
[
0
].
value
.
op
===
"
remove
"
||
if
(
results
.
data
.
rows
[
0
].
value
.
op
===
"
remove
"
||
results
.
data
.
rows
[
0
].
value
.
op
===
"
removeAttachment
"
)
{
results
.
data
.
rows
[
0
].
value
.
op
===
"
removeAttachment
"
)
{
throw
new
jIO
.
util
.
jIOError
(
throwRemovedError
(
id
);
"
HistoryStorage: cannot find object '
"
+
id
+
"
' (removed)
"
,
404
);
}
}
return
substorage
.
getAttachment
(
results
.
data
.
rows
[
0
].
id
,
name
)
return
substorage
.
getAttachment
(
results
.
data
.
rows
[
0
].
id
,
name
);
.
push
(
undefined
,
function
(
error
)
{
if
(
error
.
status_code
===
404
&&
error
instanceof
jIO
.
util
.
jIOError
)
{
throw
new
jIO
.
util
.
jIOError
(
"
HistoryStorage: cannot find object '
"
+
id
+
"
'
"
,
404
);
}
}
throw
error
;
throwCantFindError
(
id
);
});
}
return
substorage
.
getAttachment
(
id
,
name
)
.
push
(
undefined
,
function
(
error
)
{
if
(
error
.
status_code
===
404
&&
error
instanceof
jIO
.
util
.
jIOError
)
{
throw
new
jIO
.
util
.
jIOError
(
"
HistoryStorage: cannot find object '
"
+
id
+
"
'
"
,
404
);
}
throw
error
;
});
});
});
};
};
HistoryStorage
.
prototype
.
removeAttachment
=
function
(
id
,
name
)
{
HistoryStorage
.
prototype
.
removeAttachment
=
function
(
id
,
name
)
{
var
timestamp
=
unique_t
imestamp
(
Date
.
now
()),
var
timestamp
=
generateUniqueT
imestamp
(
Date
.
now
()),
metadata
=
{
metadata
=
{
// XXX: remove this attribute once query can sort_on id
// XXX: remove this attribute once query can sort_on id
timestamp
:
timestamp
,
timestamp
:
timestamp
,
...
@@ -308,7 +323,6 @@
...
@@ -308,7 +323,6 @@
name
:
name
,
name
:
name
,
op
:
"
removeAttachment
"
op
:
"
removeAttachment
"
};
};
this
.
_timestamps
[
id
][
name
].
push
(
timestamp
);
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
);
return
this
.
_sub_storage
.
put
(
timestamp
,
metadata
);
};
};
HistoryStorage
.
prototype
.
repair
=
function
()
{
HistoryStorage
.
prototype
.
repair
=
function
()
{
...
@@ -319,49 +333,27 @@
...
@@ -319,49 +333,27 @@
};
};
HistoryStorage
.
prototype
.
buildQuery
=
function
(
options
)
{
HistoryStorage
.
prototype
.
buildQuery
=
function
(
options
)
{
// XXX: if include_revisions, we should also include the document results
// for different edits of attachments
// Set default values
// Set default values
if
(
options
===
undefined
)
{
if
(
options
===
undefined
)
{
options
=
{};
}
options
=
{};
if
(
options
.
query
===
undefined
)
{
options
.
query
=
""
;
}
}
if
(
options
.
sort_on
===
undefined
)
{
options
.
sort_on
=
[];
}
if
(
options
.
query
===
undefined
)
{
if
(
options
.
select_list
===
undefined
)
{
options
.
select_list
=
[];
}
options
.
query
=
""
;
if
(
options
.
include_revisions
===
undefined
)
{
}
options
.
include_revisions
=
false
;
if
(
options
.
sort_on
===
undefined
)
{
options
.
sort_on
=
[];
}
if
(
options
.
select_list
===
undefined
)
{
options
.
select_list
=
[];
}
}
options
.
sort_on
.
push
([
"
timestamp
"
,
"
descending
"
]);
options
.
sort_on
.
push
([
"
timestamp
"
,
"
descending
"
]);
options
.
query
=
jIO
.
QueryFactory
.
create
(
options
.
query
);
options
.
query
=
jIO
.
QueryFactory
.
create
(
options
.
query
);
var
meta_options
,
var
meta_options
,
substorage
=
this
.
_sub_storage
,
substorage
=
this
.
_sub_storage
,
// Check if query involved _REVISION. If not, we will later place a
// Check if query involved _timestamp.
// (*) AND (_REVISION: =0) as the default handling of revisions
// If not, use default behavior and only query on latest revisions
rev_query
=
false
,
rev_query
=
options
.
include_revisions
,
query_obj
=
options
.
query
,
doc_id_name
,
query_stack
=
[],
timestamp_name
;
ind
;
if
(
query_obj
instanceof
ComplexQuery
)
{
query_stack
.
push
(
query_obj
);
}
else
{
rev_query
=
(
query_obj
.
key
===
"
_timestamp
"
);
}
// Traverse through query tree to find mentions of _timestamp
// and stop as soon as it is found once
while
(
query_stack
.
length
>
0
&&
(
!
rev_query
))
{
query_obj
=
query_stack
.
pop
();
for
(
ind
=
0
;
ind
<
query_obj
.
query_list
.
length
;
ind
+=
1
)
{
if
(
query_obj
.
query_list
[
ind
].
hasOwnProperty
(
"
query_list
"
))
{
query_stack
.
push
(
query_obj
.
query_list
[
ind
]);
}
else
if
(
query_obj
.
query_list
[
ind
].
key
===
"
_timestamp
"
)
{
rev_query
=
true
;
break
;
}
}
}
// Query for all edits putting or removing documents (and nothing about
// Query for all edits putting or removing documents (and nothing about
// attachments)
// attachments)
...
@@ -382,7 +374,8 @@
...
@@ -382,7 +374,8 @@
.
push
(
function
(
results
)
{
.
push
(
function
(
results
)
{
var
seen
=
{},
var
seen
=
{},
query_matches
,
query_matches
,
docs_to_query
;
docs_to_query
,
i
;
// If !rev_query, then by default only consider latest revisions of
// If !rev_query, then by default only consider latest revisions of
// documents
// documents
results
=
results
.
filter
(
function
(
docum
)
{
results
=
results
.
filter
(
function
(
docum
)
{
...
@@ -395,29 +388,47 @@
...
@@ -395,29 +388,47 @@
}
}
return
false
;
return
false
;
});
});
// If any documents have property _doc_id, __doc_id, etc, then set
// doc_id_name to the first string which is not a property of any
// of the documents
doc_id_name
=
"
_doc_id
"
;
timestamp_name
=
"
_timestamp
"
;
for
(
i
=
0
;
i
<
results
.
length
;
i
+=
1
)
{
while
(
results
[
i
].
doc
.
hasOwnProperty
(
doc_id_name
))
{
doc_id_name
=
"
_
"
+
doc_id_name
;
}
while
(
results
[
i
].
doc
.
hasOwnProperty
(
timestamp_name
))
{
timestamp_name
=
"
_
"
+
timestamp_name
;
}
}
docs_to_query
=
results
.
map
(
function
(
docum
)
{
docs_to_query
=
results
.
map
(
function
(
docum
)
{
// If it's a "remove" operation
// If it's a "remove" operation
then it has no doc property
if
(
!
docum
.
hasOwnProperty
(
"
doc
"
))
{
if
(
!
docum
.
hasOwnProperty
(
"
doc
"
))
{
docum
.
doc
=
{};
docum
.
doc
=
{};
}
}
docum
.
doc
.
_doc_id
=
docum
.
doc_id
;
docum
.
doc
[
doc_id_name
]
=
docum
.
doc_id
;
docum
.
doc
.
_timestamp
=
docum
.
timestamp
;
docum
.
doc
[
timestamp_name
]
=
docum
.
timestamp
;
return
docum
.
doc
;
return
docum
.
doc
;
});
});
options
.
select_list
.
push
(
"
_doc_id
"
);
options
.
select_list
.
push
(
doc_id_name
);
options
.
select_list
.
push
(
timestamp_name
);
query_matches
=
options
.
query
.
exec
(
docs_to_query
,
options
);
query_matches
=
options
.
query
.
exec
(
docs_to_query
,
options
);
return
query_matches
;
return
query_matches
;
})
})
// Format the results of the query, and return
// Format the results of the query, and return
.
push
(
function
(
query_matches
)
{
.
push
(
function
(
query_matches
)
{
return
query_matches
.
map
(
function
(
docum
)
{
return
query_matches
.
map
(
function
(
docum
)
{
var
doc_id
=
docum
.
_doc_id
;
var
doc_id
=
docum
[
doc_id_name
],
delete
docum
.
_timestamp
;
time
=
docum
[
timestamp_name
];
delete
docum
.
_doc_id
;
delete
docum
[
timestamp_name
];
delete
docum
[
doc_id_name
];
return
{
return
{
doc
:
{},
doc
:
{},
value
:
docum
,
value
:
docum
,
id
:
doc_id
id
:
doc_id
,
timestamp
:
time
};
};
});
});
});
});
...
...
test/jio.storage/historystorage.tests.js
View file @
c6db8c50
...
@@ -64,36 +64,47 @@
...
@@ -64,36 +64,47 @@
test
(
"
Testing proper adding/removing attachments
"
,
test
(
"
Testing proper adding/removing attachments
"
,
function
()
{
function
()
{
stop
();
stop
();
expect
(
9
);
expect
(
10
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
timestamps
=
this
.
jio
.
__storage
.
_timestamps
,
not_history
=
this
.
not_history
,
timestamps
,
blob2
=
this
.
blob2
,
blob2
=
this
.
blob2
,
blob1
=
this
.
blob1
,
blob1
=
this
.
blob1
,
other_blob
=
this
.
other_blob
,
other_blob
=
this
.
other_blob
,
otherother_blob
=
new
Blob
([
'
abcabc
'
]);
otherother_blob
=
new
Blob
([
'
abcabc
'
]);
jio
.
put
(
"
doc
"
,
{
title
:
"
foo0
"
})
jio
.
put
(
"
doc
"
,
{
title
:
"
foo0
"
})
// 0
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
put
(
"
doc2
"
,
{
key
:
"
val
"
});
return
jio
.
put
(
"
doc2
"
,
{
key
:
"
val
"
});
// 1
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
putAttachment
(
"
doc
"
,
"
attacheddata
"
,
blob1
);
return
jio
.
putAttachment
(
"
doc
"
,
"
attacheddata
"
,
blob1
);
// 2
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
putAttachment
(
"
doc
"
,
"
attacheddata
"
,
blob2
);
return
jio
.
putAttachment
(
"
doc
"
,
"
attacheddata
"
,
blob2
);
// 3
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
putAttachment
(
"
doc
"
,
"
other_attacheddata
"
,
other_blob
);
return
jio
.
putAttachment
(
"
doc
"
,
"
other_attacheddata
"
,
other_blob
);
// 4
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
putAttachment
(
return
jio
.
putAttachment
(
// 5
"
doc
"
,
"
doc
"
,
"
otherother_attacheddata
"
,
"
otherother_attacheddata
"
,
otherother_blob
otherother_blob
);
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
removeAttachment
(
"
doc
"
,
"
otherother_attacheddata
"
);
return
jio
.
removeAttachment
(
"
doc
"
,
"
otherother_attacheddata
"
);
// 6
})
.
push
(
function
()
{
return
not_history
.
allDocs
({
sort_on
:
[[
"
timestamp
"
,
"
ascending
"
]]
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
id
;
});
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
get
(
"
doc
"
);
return
jio
.
get
(
"
doc
"
);
...
@@ -110,7 +121,7 @@
...
@@ -110,7 +121,7 @@
"
Return the attachment information with getAttachment
"
"
Return the attachment information with getAttachment
"
);
);
return
jio
.
getAttachment
(
return
jio
.
getAttachment
(
timestamps
.
doc
.
attacheddata
[
1
],
timestamps
[
3
],
"
attacheddata
"
"
attacheddata
"
);
);
})
})
...
@@ -121,7 +132,7 @@
...
@@ -121,7 +132,7 @@
"
current revision
"
"
current revision
"
);
);
return
jio
.
getAttachment
(
return
jio
.
getAttachment
(
timestamps
.
doc
.
attacheddata
[
0
],
timestamps
[
2
],
"
attacheddata
"
"
attacheddata
"
);
);
},
function
(
error
)
{
},
function
(
error
)
{
...
@@ -134,7 +145,7 @@
...
@@ -134,7 +145,7 @@
"
Return the attachment information with getAttachment for
"
+
"
Return the attachment information with getAttachment for
"
+
"
previous revision
"
"
previous revision
"
);
);
return
jio
.
getAttachment
(
timestamps
.
doc
[
0
],
"
attached
"
);
return
jio
.
getAttachment
(
timestamps
[
0
],
"
attached
"
);
},
function
(
error
)
{
},
function
(
error
)
{
ok
(
false
,
error
);
ok
(
false
,
error
);
})
})
...
@@ -146,6 +157,9 @@
...
@@ -146,6 +157,9 @@
deepEqual
(
error
.
status_code
,
deepEqual
(
error
.
status_code
,
404
,
404
,
"
Error if you try to go back to a nonexistent timestamp
"
);
"
Error if you try to go back to a nonexistent timestamp
"
);
deepEqual
(
error
.
message
,
"
HistoryStorage: cannot find object '
"
+
timestamps
[
0
]
+
"
'
"
,
"
Error caught by history storage correctly
"
);
return
jio
.
getAttachment
(
"
doc
"
,
"
other_attacheddata
"
);
return
jio
.
getAttachment
(
"
doc
"
,
"
other_attacheddata
"
);
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
...
@@ -208,10 +222,10 @@
...
@@ -208,10 +222,10 @@
.
always
(
function
()
{
start
();
});
.
always
(
function
()
{
start
();
});
});
});
test
(
"
Correctness of allAttachments method
"
,
test
(
"
Correctness of allAttachments method
on current attachments
"
,
function
()
{
function
()
{
stop
();
stop
();
expect
(
1
1
);
expect
(
1
4
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
,
not_history
=
this
.
not_history
,
blob1
=
this
.
blob1
,
blob1
=
this
.
blob1
,
...
@@ -317,7 +331,7 @@
...
@@ -317,7 +331,7 @@
}));
}));
})
})
.
push
(
function
(
results
)
{
.
push
(
function
(
results
)
{
equal
(
results
.
length
,
7
,
"
Seven document revisions in storage
(17)
"
);
equal
(
results
.
length
,
7
,
"
Seven document revisions in storage
"
);
return
jio
.
remove
(
"
doc
"
);
return
jio
.
remove
(
"
doc
"
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
...
@@ -332,6 +346,132 @@
...
@@ -332,6 +346,132 @@
404
,
404
,
"
Cannot get the attachment of a removed document
"
);
"
Cannot get the attachment of a removed document
"
);
})
})
.
push
(
function
()
{
return
jio
.
allAttachments
(
"
doc
"
);
})
.
push
(
function
()
{
ok
(
false
,
"
This query should have thrown a 404 error
"
);
},
function
(
error
)
{
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
throws a jio error
"
);
deepEqual
(
error
.
status_code
,
404
,
"
allAttachments of a removed document throws a 404 error
"
);
deepEqual
(
error
.
message
,
"
HistoryStorage: cannot find object 'doc' (removed)
"
,
"
Error is handled by Historystorage.
"
);
})
.
fail
(
function
(
error
)
{
//console.log(error);
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
test
(
"
Correctness of allAttachments method on older revisions
"
,
function
()
{
stop
();
expect
(
8
);
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
,
blob1
=
new
Blob
([
'
a
'
]),
blob11
=
new
Blob
([
'
ab
'
]),
blob2
=
new
Blob
([
'
abc
'
]),
blob22
=
new
Blob
([
'
abcd
'
]),
timestamps
;
jio
.
put
(
"
doc
"
,
{
title
:
"
foo0
"
})
// 0
.
push
(
function
()
{
return
jio
.
putAttachment
(
"
doc
"
,
"
data
"
,
blob1
);
})
.
push
(
function
()
{
return
jio
.
putAttachment
(
"
doc
"
,
"
data2
"
,
blob2
);
})
.
push
(
function
()
{
return
jio
.
put
(
"
doc
"
,
{
title
:
"
foo1
"
});
// 1
})
.
push
(
function
()
{
return
jio
.
removeAttachment
(
"
doc
"
,
"
data2
"
);
})
.
push
(
function
()
{
return
jio
.
put
(
"
doc
"
,
{
title
:
"
foo2
"
});
// 2
})
.
push
(
function
()
{
return
jio
.
putAttachment
(
"
doc
"
,
"
data
"
,
blob11
);
})
.
push
(
function
()
{
return
jio
.
remove
(
"
doc
"
);
// 3
})
.
push
(
function
()
{
return
jio
.
put
(
"
doc
"
,
{
title
:
"
foo3
"
});
// 4
})
.
push
(
function
()
{
return
jio
.
putAttachment
(
"
doc
"
,
"
data2
"
,
blob22
);
})
.
push
(
function
()
{
return
not_history
.
allDocs
({
query
:
"
op: put OR op: remove
"
,
sort_on
:
[[
"
timestamp
"
,
"
ascending
"
]],
select_list
:
[
"
timestamp
"
]
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
value
.
timestamp
;
});
})
.
push
(
function
()
{
return
jio
.
allAttachments
(
"
doc
"
);
})
.
push
(
function
(
results
)
{
deepEqual
(
results
,
{
"
data
"
:
blob11
,
"
data2
"
:
blob22
},
"
Current state of document is correct
"
);
return
jio
.
allAttachments
(
timestamps
[
0
]);
})
.
push
(
function
(
results
)
{
deepEqual
(
results
,
{},
"
First version of document has 0 attachments
"
);
return
jio
.
allAttachments
(
timestamps
[
1
]);
})
.
push
(
function
(
results
)
{
deepEqual
(
results
,
{
data
:
blob1
,
data2
:
blob2
},
"
Both attachments are included in allAttachments
"
);
return
jio
.
allAttachments
(
timestamps
[
2
]);
})
.
push
(
function
(
results
)
{
deepEqual
(
results
,
{
data
:
blob1
},
"
Removed attachment does not show up in allAttachments
"
);
return
jio
.
allAttachments
(
timestamps
[
3
]);
})
.
push
(
function
()
{
ok
(
false
,
"
This query should have thrown a 404 error
"
);
},
function
(
error
)
{
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
throws a jio error
"
);
deepEqual
(
error
.
status_code
,
404
,
"
allAttachments of a removed document throws a 404 error
"
);
deepEqual
(
error
.
message
,
"
HistoryStorage: cannot find object '
"
+
timestamps
[
3
]
+
"
' (removed)
"
,
"
Error is handled by Historystorage.
"
);
})
.
push
(
function
()
{
return
jio
.
allAttachments
(
timestamps
[
4
]);
})
.
push
(
function
(
results
)
{
deepEqual
(
results
,
{
data
:
blob11
});
})
.
fail
(
function
(
error
)
{
.
fail
(
function
(
error
)
{
//console.log(error);
//console.log(error);
ok
(
false
,
error
);
ok
(
false
,
error
);
...
@@ -377,49 +517,48 @@
...
@@ -377,49 +517,48 @@
test
(
"
Handling bad input
"
,
test
(
"
Handling bad input
"
,
function
()
{
function
()
{
stop
();
stop
();
expect
(
6
);
expect
(
2
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
BADINPUT_ERRCODE
=
422
;
BADINPUT_ERRCODE
=
422
;
jio
.
put
(
"
doc
"
,
{
jio
.
put
(
"
1234567891123-ab7d
"
,
{})
"
_timestamp
"
:
3
,
"
other_attr
"
:
"
other_val
"
})
.
push
(
function
()
{
.
push
(
function
()
{
ok
(
false
,
"
This statement should not be reached
"
);
ok
(
false
,
"
This statement should not be reached
"
);
},
function
(
error
)
{
},
function
(
error
)
{
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
deepEqual
(
error
.
status_code
,
deepEqual
(
error
.
status_code
,
BADINPUT_ERRCODE
,
BADINPUT_ERRCODE
,
"
Can't save a document with a
reserved keywor
d
"
"
Can't save a document with a
timestamp-formatted i
d
"
);
);
})
})
.
push
(
function
()
{
.
fail
(
function
(
error
)
{
return
jio
.
put
(
"
doc
"
,
{
//console.log(error);
"
_doc_id
"
:
3
,
ok
(
false
,
error
);
"
other_attr
"
:
"
other_val
"
});
})
.
push
(
function
()
{
ok
(
false
,
"
This statement should not be reached
"
);
},
function
(
error
)
{
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
deepEqual
(
error
.
status_code
,
BADINPUT_ERRCODE
,
"
Can't save a document with a reserved keyword
"
);
})
})
.
always
(
function
()
{
start
();
});
});
test
(
"
Getting a non-existent document
"
,
function
()
{
stop
();
expect
(
3
);
var
jio
=
this
.
jio
;
jio
.
put
(
"
not_doc
"
,
{})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
put
(
"
1234567891123-ab7d
"
,
{}
);
return
jio
.
get
(
"
doc
"
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
ok
(
false
,
"
This statement should not be reached
"
);
ok
(
false
,
"
This statement should not be reached
"
);
},
function
(
error
)
{
},
function
(
error
)
{
//console.log(error);
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
deepEqual
(
error
.
status_code
,
deepEqual
(
error
.
status_code
,
BADINPUT_ERRCODE
,
404
,
"
C
an't save a document with a timestamp-formatted id
"
"
C
orrect status code for getting a non-existent document
"
);
);
deepEqual
(
error
.
message
,
"
HistoryStorage: cannot find object 'doc'
"
,
"
Error is handled by history storage before reaching console
"
);
})
})
.
fail
(
function
(
error
)
{
.
fail
(
function
(
error
)
{
//console.log(error);
//console.log(error);
...
@@ -431,31 +570,39 @@
...
@@ -431,31 +570,39 @@
test
(
"
Creating a document with put and retrieving it with get
"
,
test
(
"
Creating a document with put and retrieving it with get
"
,
function
()
{
function
()
{
stop
();
stop
();
expect
(
4
);
expect
(
7
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
,
not_history
=
this
.
not_history
,
timestamps
=
jio
.
__storage
.
_timestamps
;
timestamps
;
jio
.
put
(
"
doc
"
,
{
title
:
"
version0
"
})
jio
.
put
(
"
doc
"
,
{
title
:
"
version0
"
})
.
push
(
function
()
{
.
push
(
function
()
{
ok
(
timestamps
.
hasOwnProperty
(
"
doc
"
),
return
not_history
.
allDocs
({
"
jio._timestamps is updated with new document.
"
);
select_list
:
[
"
timestamp
"
]
equal
(
timestamps
.
doc
.
length
,
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
value
.
timestamp
;
});
})
.
push
(
function
()
{
equal
(
timestamps
.
length
,
1
,
1
,
"
One revision is
logged in jio._timestamps
"
"
One revision is
saved in storage
"
);
);
return
jio
.
get
(
timestamps
.
doc
[
0
]);
return
jio
.
get
(
timestamps
[
0
]);
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
deepEqual
(
result
,
{
deepEqual
(
result
,
{
title
:
"
version0
"
title
:
"
version0
"
},
"
Get document from history storage
"
);
},
"
Get document from history storage
"
);
return
not_history
.
get
(
return
not_history
.
get
(
timestamps
.
doc
[
0
]
timestamps
[
0
]
);
);
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
deepEqual
(
result
,
{
deepEqual
(
result
,
{
timestamp
:
timestamps
.
doc
[
0
],
timestamp
:
timestamps
[
0
],
op
:
"
put
"
,
op
:
"
put
"
,
doc_id
:
"
doc
"
,
doc_id
:
"
doc
"
,
doc
:
{
doc
:
{
...
@@ -463,6 +610,31 @@
...
@@ -463,6 +610,31 @@
}
}
},
"
Get document from non-history storage
"
);
},
"
Get document from non-history storage
"
);
})
})
.
push
(
function
()
{
return
jio
.
get
(
"
non-existent-doc
"
);
})
.
push
(
function
()
{
ok
(
false
,
"
This should have thrown an error
"
);
},
function
(
error
)
{
//console.log(error);
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
deepEqual
(
error
.
status_code
,
404
,
"
Can't access non-existent document
"
);
})
.
push
(
function
()
{
return
jio
.
get
(
"
1234567891123-abcd
"
);
})
.
push
(
function
()
{
ok
(
false
,
"
Trying to get a non-existent id should have raised 404
"
);
},
function
(
error
)
{
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
deepEqual
(
error
.
status_code
,
404
,
"
Can't access document by getting with non-existent id
"
);
})
.
fail
(
function
(
error
)
{
.
fail
(
function
(
error
)
{
//console.log(error);
//console.log(error);
ok
(
false
,
error
);
ok
(
false
,
error
);
...
@@ -475,7 +647,8 @@
...
@@ -475,7 +647,8 @@
stop
();
stop
();
expect
(
7
);
expect
(
7
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
timestamps
=
this
.
jio
.
__storage
.
_timestamps
;
not_history
=
this
.
not_history
,
timestamps
;
return
jio
.
put
(
"
doc
"
,
{
title
:
"
t0
"
,
subtitle
:
"
s0
"
})
return
jio
.
put
(
"
doc
"
,
{
title
:
"
t0
"
,
subtitle
:
"
s0
"
})
.
push
(
function
()
{
.
push
(
function
()
{
...
@@ -490,6 +663,17 @@
...
@@ -490,6 +663,17 @@
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
put
(
"
doc
"
,
{
title
:
"
t3
"
,
subtitle
:
"
s3
"
});
return
jio
.
put
(
"
doc
"
,
{
title
:
"
t3
"
,
subtitle
:
"
s3
"
});
})
})
.
push
(
function
()
{
return
not_history
.
allDocs
({
select_list
:
[
"
timestamp
"
],
sort_on
:
[[
"
timestamp
"
,
"
ascending
"
]]
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
value
.
timestamp
;
});
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
get
(
"
doc
"
);
return
jio
.
get
(
"
doc
"
);
})
})
...
@@ -498,7 +682,7 @@
...
@@ -498,7 +682,7 @@
title
:
"
t3
"
,
title
:
"
t3
"
,
subtitle
:
"
s3
"
subtitle
:
"
s3
"
},
"
Get returns latest revision
"
);
},
"
Get returns latest revision
"
);
return
jio
.
get
(
timestamps
.
doc
[
0
]);
return
jio
.
get
(
timestamps
[
0
]);
},
function
(
err
)
{
},
function
(
err
)
{
ok
(
false
,
err
);
ok
(
false
,
err
);
})
})
...
@@ -507,14 +691,14 @@
...
@@ -507,14 +691,14 @@
title
:
"
t0
"
,
title
:
"
t0
"
,
subtitle
:
"
s0
"
subtitle
:
"
s0
"
},
"
Get returns first version
"
);
},
"
Get returns first version
"
);
return
jio
.
get
(
timestamps
.
doc
[
1
]);
return
jio
.
get
(
timestamps
[
1
]);
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
deepEqual
(
result
,
{
deepEqual
(
result
,
{
title
:
"
t1
"
,
title
:
"
t1
"
,
subtitle
:
"
s1
"
subtitle
:
"
s1
"
},
"
Get returns second version
"
);
},
"
Get returns second version
"
);
return
jio
.
get
(
timestamps
.
doc
[
2
]);
return
jio
.
get
(
timestamps
[
2
]);
},
function
(
err
)
{
},
function
(
err
)
{
ok
(
false
,
err
);
ok
(
false
,
err
);
})
})
...
@@ -523,20 +707,20 @@
...
@@ -523,20 +707,20 @@
title
:
"
t2
"
,
title
:
"
t2
"
,
subtitle
:
"
s2
"
subtitle
:
"
s2
"
},
"
Get returns third version
"
);
},
"
Get returns third version
"
);
return
jio
.
get
(
timestamps
.
doc
[
3
]);
return
jio
.
get
(
timestamps
[
3
]);
},
function
(
err
)
{
},
function
(
err
)
{
ok
(
false
,
err
);
ok
(
false
,
err
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
ok
(
false
,
"
This should have thrown a 404 error
"
);
ok
(
false
,
"
This should have thrown a 404 error
"
);
return
jio
.
get
(
timestamps
.
doc
[
4
]);
return
jio
.
get
(
timestamps
[
4
]);
},
},
function
(
error
)
{
function
(
error
)
{
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
ok
(
error
instanceof
jIO
.
util
.
jIOError
,
"
Correct type of error
"
);
deepEqual
(
error
.
status_code
,
deepEqual
(
error
.
status_code
,
404
,
404
,
"
Error if you try to go back more revisions than what exists
"
);
"
Error if you try to go back more revisions than what exists
"
);
return
jio
.
get
(
timestamps
.
doc
[
4
]);
return
jio
.
get
(
timestamps
[
4
]);
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
deepEqual
(
result
,
{
deepEqual
(
result
,
{
...
@@ -674,8 +858,18 @@
...
@@ -674,8 +858,18 @@
stop
();
stop
();
expect
(
7
);
expect
(
7
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
;
not_history
=
this
.
not_history
,
timestamp
;
jio
.
put
(
"
doc
"
,
{
title
:
"
version0
"
})
jio
.
put
(
"
doc
"
,
{
title
:
"
version0
"
})
.
push
(
function
()
{
return
not_history
.
allDocs
({
query
:
"
doc_id: doc
"
,
select_list
:
[
"
timestamp
"
]
});
})
.
push
(
function
(
results
)
{
timestamp
=
results
.
data
.
rows
[
0
].
value
.
timestamp
;
})
.
push
(
function
()
{
.
push
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
jio
.
allDocs
(),
jio
.
allDocs
(),
...
@@ -701,7 +895,8 @@
...
@@ -701,7 +895,8 @@
deepEqual
(
results
.
data
.
rows
[
0
],
{
deepEqual
(
results
.
data
.
rows
[
0
],
{
doc
:
{},
doc
:
{},
value
:
{},
value
:
{},
id
:
"
doc
"
id
:
"
doc
"
,
timestamp
:
timestamp
},
},
"
Correct document format is returned.
"
"
Correct document format is returned.
"
);
);
...
@@ -715,7 +910,7 @@
...
@@ -715,7 +910,7 @@
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
deepEqual
(
result
,
{
deepEqual
(
result
,
{
timestamp
:
jio
.
__storage
.
_timestamps
.
doc
[
0
]
,
timestamp
:
timestamp
,
doc_id
:
"
doc
"
,
doc_id
:
"
doc
"
,
doc
:
{
doc
:
{
title
:
"
version0
"
title
:
"
version0
"
...
@@ -733,14 +928,69 @@
...
@@ -733,14 +928,69 @@
.
always
(
function
()
{
start
();
});
.
always
(
function
()
{
start
();
});
});
});
test
(
"
Putting doc with _doc_id and _timestamp properties
"
+
"
and retrieving them with allDocs
"
,
function
()
{
stop
();
expect
(
1
);
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
,
timestamp
;
jio
.
put
(
"
doc
"
,
{
title
:
"
version0
"
,
_doc_id
:
"
bar
"
,
__doc_id
:
"
bar2
"
,
___doc_id
:
"
bar3
"
,
_timestamp
:
"
foo
"
,
____timestamp
:
"
foo2
"
})
.
push
(
function
()
{
return
not_history
.
allDocs
({
query
:
"
doc_id: doc
"
,
select_list
:
[
"
timestamp
"
]
});
})
.
push
(
function
(
results
)
{
timestamp
=
results
.
data
.
rows
[
0
].
value
.
timestamp
;
})
.
push
(
function
()
{
return
jio
.
allDocs
({
query
:
"
title: version0 AND _timestamp: >= 0
"
,
select_list
:
[
"
title
"
,
"
_doc_id
"
,
"
__doc_id
"
,
"
___doc_id
"
,
"
_timestamp
"
,
"
____timestamp
"
]
});
})
.
push
(
function
(
results
)
{
deepEqual
(
results
.
data
.
rows
,
[
{
doc
:
{},
id
:
"
doc
"
,
value
:
{
title
:
"
version0
"
,
_doc_id
:
"
bar
"
,
__doc_id
:
"
bar2
"
,
___doc_id
:
"
bar3
"
,
_timestamp
:
"
foo
"
,
____timestamp
:
"
foo2
"
},
timestamp
:
timestamp
}],
"
_doc_id properties are not overwritten in allDocs call
"
);
})
.
fail
(
function
(
error
)
{
//console.log(error);
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
test
(
"
Putting a document, revising it, and retrieving revisions with allDocs
"
,
test
(
"
Putting a document, revising it, and retrieving revisions with allDocs
"
,
function
()
{
function
()
{
stop
();
stop
();
expect
(
1
4
);
expect
(
1
0
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
,
not_history
=
this
.
not_history
,
timestamps
=
this
.
jio
.
__storage
.
_timestamps
;
timestamps
;
jio
.
put
(
"
doc
"
,
{
jio
.
put
(
"
doc
"
,
{
title
:
"
version0
"
,
title
:
"
version0
"
,
subtitle
:
"
subvers0
"
subtitle
:
"
subvers0
"
...
@@ -757,6 +1007,17 @@
...
@@ -757,6 +1007,17 @@
subtitle
:
"
subvers2
"
subtitle
:
"
subvers2
"
});
});
})
})
.
push
(
function
()
{
return
not_history
.
allDocs
({
select_list
:
[
"
timestamp
"
],
sort_on
:
[[
"
timestamp
"
,
"
ascending
"
]]
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
value
.
timestamp
;
});
})
.
push
(
function
()
{
.
push
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
jio
.
allDocs
({
select_list
:
[
"
title
"
,
"
subtitle
"
]}),
jio
.
allDocs
({
select_list
:
[
"
title
"
,
"
subtitle
"
]}),
...
@@ -803,73 +1064,52 @@
...
@@ -803,73 +1064,52 @@
subtitle
:
"
subvers2
"
subtitle
:
"
subvers2
"
},
},
doc
:
{},
doc
:
{},
id
:
"
doc
"
id
:
"
doc
"
,
timestamp
:
timestamps
[
2
]
},
},
"
Correct document format is returned.
"
"
Correct document format is returned.
"
);
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
// These are all equivalent queries in that they should return the
return
jio
.
allDocs
({
// same documents in the correct order
query
:
""
,
return
RSVP
.
all
([
select_list
:
[
"
title
"
,
"
subtitle
"
],
jio
.
allDocs
({
include_revisions
:
true
query
:
"
_timestamp:
"
+
timestamps
.
doc
[
1
],
});
select_list
:
[
"
title
"
,
"
subtitle
"
]
}),
jio
.
allDocs
({
query
:
"
_timestamp: =
"
+
timestamps
.
doc
[
1
],
select_list
:
[
"
title
"
,
"
subtitle
"
]
}),
jio
.
allDocs
({
query
:
"
_timestamp: >
"
+
timestamps
.
doc
[
0
]
+
"
AND title: version1
"
,
select_list
:
[
"
title
"
,
"
subtitle
"
]
}),
jio
.
allDocs
({
query
:
"
_timestamp: >
"
+
timestamps
.
doc
[
0
]
+
"
AND _timestamp: <
"
+
timestamps
.
doc
[
2
],
select_list
:
[
"
title
"
,
"
subtitle
"
]
})
]);
})
.
push
(
function
(
results
)
{
equal
(
results
[
0
].
data
.
rows
.
length
,
1
,
"
Querying a specific timestamp retrieves one document
"
);
var
ind
=
0
;
for
(
ind
=
0
;
ind
<
results
.
length
-
1
;
ind
+=
1
)
{
deepEqual
(
results
[
ind
],
results
[
ind
+
1
],
"
Each query returns exactly the same correct output
"
);
}
return
results
[
0
];
})
})
.
push
(
function
(
results
)
{
.
push
(
function
(
results
)
{
deepEqual
(
results
.
data
.
rows
[
0
],
{
equal
(
results
.
data
.
rows
.
length
,
3
,
"
Querying with include_revisions retrieves all versions
"
);
deepEqual
(
results
.
data
.
rows
,
[
{
id
:
"
doc
"
,
value
:
{
title
:
"
version2
"
,
subtitle
:
"
subvers2
"
},
doc
:
{},
timestamp
:
timestamps
[
2
]
},
{
id
:
"
doc
"
,
id
:
"
doc
"
,
value
:
{
value
:
{
title
:
"
version1
"
,
title
:
"
version1
"
,
subtitle
:
"
subvers1
"
subtitle
:
"
subvers1
"
},
},
doc
:
{}
doc
:
{},
});
timestamp
:
timestamps
[
1
]
return
jio
.
allDocs
({
},
query
:
"
_timestamp:
"
+
timestamps
.
doc
[
0
],
select_list
:
[
"
title
"
,
"
subtitle
"
]
});
})
.
push
(
function
(
results
)
{
deepEqual
(
results
.
data
.
rows
,
[
{
{
id
:
"
doc
"
,
value
:
{
value
:
{
title
:
"
version0
"
,
title
:
"
version0
"
,
subtitle
:
"
subvers0
"
subtitle
:
"
subvers0
"
},
},
doc
:
{},
doc
:
{},
id
:
"
doc
"
timestamp
:
timestamps
[
0
]
}
}
],
"
Query requesting one timestamp works
.
"
);
],
"
Full version history is included
.
"
);
return
not_history
.
allDocs
({
return
not_history
.
allDocs
({
sort_on
:
[[
"
title
"
,
"
ascending
"
]]
sort_on
:
[[
"
title
"
,
"
ascending
"
]]
...
@@ -883,7 +1123,7 @@
...
@@ -883,7 +1123,7 @@
.
push
(
function
(
results
)
{
.
push
(
function
(
results
)
{
deepEqual
(
results
,
[
deepEqual
(
results
,
[
{
{
timestamp
:
timestamps
.
doc
[
0
],
timestamp
:
timestamps
[
0
],
op
:
"
put
"
,
op
:
"
put
"
,
doc_id
:
"
doc
"
,
doc_id
:
"
doc
"
,
doc
:
{
doc
:
{
...
@@ -892,7 +1132,7 @@
...
@@ -892,7 +1132,7 @@
}
}
},
},
{
{
timestamp
:
timestamps
.
doc
[
1
],
timestamp
:
timestamps
[
1
],
op
:
"
put
"
,
op
:
"
put
"
,
doc_id
:
"
doc
"
,
doc_id
:
"
doc
"
,
doc
:
{
doc
:
{
...
@@ -901,7 +1141,7 @@
...
@@ -901,7 +1141,7 @@
}
}
},
},
{
{
timestamp
:
timestamps
.
doc
[
2
],
timestamp
:
timestamps
[
2
],
op
:
"
put
"
,
op
:
"
put
"
,
doc_id
:
"
doc
"
,
doc_id
:
"
doc
"
,
doc
:
{
doc
:
{
...
@@ -924,43 +1164,54 @@
...
@@ -924,43 +1164,54 @@
"
Putting and removing documents, latest revisions and no removed documents
"
,
"
Putting and removing documents, latest revisions and no removed documents
"
,
function
()
{
function
()
{
stop
();
stop
();
expect
(
5
);
expect
(
3
);
var
history
=
this
.
jio
,
var
jio
=
this
.
jio
,
timestamps
=
this
.
jio
.
__storage
.
_timestamps
;
not_history
=
this
.
not_history
,
timestamps
;
history
.
put
(
"
doc_a
"
,
{
jio
.
put
(
"
doc_a
"
,
{
title_a
:
"
rev0
"
,
title_a
:
"
rev0
"
,
subtitle_a
:
"
subrev0
"
subtitle_a
:
"
subrev0
"
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
history
.
put
(
"
doc_a
"
,
{
return
jio
.
put
(
"
doc_a
"
,
{
title_a
:
"
rev1
"
,
title_a
:
"
rev1
"
,
subtitle_a
:
"
subrev1
"
subtitle_a
:
"
subrev1
"
});
});
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
history
.
put
(
"
doc_b
"
,
{
return
jio
.
put
(
"
doc_b
"
,
{
title_b
:
"
rev0
"
,
title_b
:
"
rev0
"
,
subtitle_b
:
"
subrev0
"
subtitle_b
:
"
subrev0
"
});
});
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
history
.
remove
(
"
doc_b
"
);
return
jio
.
remove
(
"
doc_b
"
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
history
.
put
(
"
doc_c
"
,
{
return
jio
.
put
(
"
doc_c
"
,
{
title_c
:
"
rev0
"
,
title_c
:
"
rev0
"
,
subtitle_c
:
"
subrev0
"
subtitle_c
:
"
subrev0
"
});
});
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
history
.
put
(
"
doc_c
"
,
{
return
jio
.
put
(
"
doc_c
"
,
{
title_c
:
"
rev1
"
,
title_c
:
"
rev1
"
,
subtitle_c
:
"
subrev1
"
subtitle_c
:
"
subrev1
"
});
});
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
history
.
allDocs
({
sort_on
:
[[
"
timestamp
"
,
"
descending
"
]]});
return
not_history
.
allDocs
({
sort_on
:
[[
"
timestamp
"
,
"
ascending
"
]]
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
id
;
});
})
.
push
(
function
()
{
return
jio
.
allDocs
({
sort_on
:
[[
"
timestamp
"
,
"
descending
"
]]});
})
})
.
push
(
function
(
results
)
{
.
push
(
function
(
results
)
{
equal
(
results
.
data
.
rows
.
length
,
equal
(
results
.
data
.
rows
.
length
,
...
@@ -971,24 +1222,20 @@
...
@@ -971,24 +1222,20 @@
{
{
id
:
"
doc_c
"
,
id
:
"
doc_c
"
,
value
:
{},
value
:
{},
doc
:
{}
doc
:
{},
timestamp
:
timestamps
[
5
]
},
},
{
{
id
:
"
doc_a
"
,
id
:
"
doc_a
"
,
value
:
{},
value
:
{},
doc
:
{}
doc
:
{},
timestamp
:
timestamps
[
1
]
}
}
],
],
"
Empty query returns latest revisions (and no removed documents)
"
);
"
Empty query returns latest revisions (and no removed documents)
"
);
equal
(
timestamps
.
doc_a
.
length
,
equal
(
timestamps
.
length
,
2
,
6
,
"
Correct number of revisions logged in doc_a
"
);
"
Correct number of revisions logged
"
);
equal
(
timestamps
.
doc_b
.
length
,
2
,
"
Correct number of revisions logged in doc_b
"
);
equal
(
timestamps
.
doc_c
.
length
,
2
,
"
Correct number of revisions logged in doc_c
"
);
})
})
.
fail
(
function
(
error
)
{
.
fail
(
function
(
error
)
{
//console.log(error);
//console.log(error);
...
@@ -1006,7 +1253,9 @@
...
@@ -1006,7 +1253,9 @@
function
()
{
function
()
{
stop
();
stop
();
expect
(
2
);
expect
(
2
);
var
history
=
this
.
jio
,
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
,
timestamps
,
docs
=
[
docs
=
[
{
{
"
date
"
:
1
,
"
date
"
:
1
,
...
@@ -1029,19 +1278,29 @@
...
@@ -1029,19 +1278,29 @@
new
Blob
([
'
bcd
'
]),
new
Blob
([
'
bcd
'
]),
new
Blob
([
'
eeee
'
])
new
Blob
([
'
eeee
'
])
];
];
history
.
put
(
"
doc
"
,
{})
jio
.
put
(
"
doc
"
,
{})
// 0
.
push
(
function
()
{
.
push
(
function
()
{
return
putFullDoc
(
history
,
"
doc
"
,
docs
[
0
],
"
data
"
,
blobs
[
0
]);
return
putFullDoc
(
jio
,
"
doc
"
,
docs
[
0
],
"
data
"
,
blobs
[
0
]);
// 1,2
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
putFullDoc
(
history
,
"
second_doc
"
,
docs
[
1
],
"
data
"
,
blobs
[
1
]);
return
putFullDoc
(
jio
,
"
second_doc
"
,
docs
[
1
],
"
data
"
,
blobs
[
1
]);
// 3,4
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
putFullDoc
(
history
,
"
third_doc
"
,
docs
[
2
],
"
data
"
,
blobs
[
2
]);
return
putFullDoc
(
jio
,
"
third_doc
"
,
docs
[
2
],
"
data
"
,
blobs
[
2
]);
// 5,6
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
history
.
allDocs
({
return
not_history
.
allDocs
({
query
:
"
(date: <= 2)
"
,
sort_on
:
[[
"
timestamp
"
,
"
ascending
"
]]
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
id
;
});
})
.
push
(
function
()
{
return
jio
.
allDocs
({
query
:
"
NOT (date: > 2)
"
,
select_list
:
[
"
date
"
,
"
non-existent-key
"
],
select_list
:
[
"
date
"
,
"
non-existent-key
"
],
sort_on
:
[[
"
date
"
,
"
ascending
"
],
sort_on
:
[[
"
date
"
,
"
ascending
"
],
[
"
non-existent-key
"
,
"
ascending
"
]
[
"
non-existent-key
"
,
"
ascending
"
]
...
@@ -1054,17 +1313,20 @@
...
@@ -1054,17 +1313,20 @@
{
{
doc
:
{},
doc
:
{},
id
:
"
doc
"
,
id
:
"
doc
"
,
value
:
{
date
:
1
}
value
:
{
date
:
1
},
timestamp
:
timestamps
[
1
]
},
},
{
{
doc
:
{},
doc
:
{},
id
:
"
third_doc
"
,
id
:
"
third_doc
"
,
value
:
{
date
:
2
}
value
:
{
date
:
2
},
timestamp
:
timestamps
[
5
]
},
},
{
{
doc
:
{},
doc
:
{},
id
:
"
second_doc
"
,
id
:
"
second_doc
"
,
value
:
{
date
:
2
}
value
:
{
date
:
2
},
timestamp
:
timestamps
[
3
]
}
}
],
],
"
Query gives correct results in correct order
"
);
"
Query gives correct results in correct order
"
);
...
@@ -1086,7 +1348,7 @@
...
@@ -1086,7 +1348,7 @@
expect
(
3
);
expect
(
3
);
var
jio
=
this
.
jio
,
var
jio
=
this
.
jio
,
not_history
=
this
.
not_history
,
not_history
=
this
.
not_history
,
timestamps
=
this
.
jio
.
__storage
.
_timestamps
,
timestamps
,
docs
=
[
docs
=
[
{
{
"
date
"
:
1
,
"
date
"
:
1
,
...
@@ -1106,11 +1368,11 @@
...
@@ -1106,11 +1368,11 @@
new
Blob
([
'
bcd2
'
]),
new
Blob
([
'
bcd2
'
]),
new
Blob
([
'
a3
'
])
new
Blob
([
'
a3
'
])
];
];
jio
.
put
(
"
doc
"
,
{})
jio
.
put
(
"
doc
"
,
{})
// 0
.
push
(
function
()
{
.
push
(
function
()
{
// 1,2
return
putFullDoc
(
jio
,
"
doc
"
,
docs
[
0
],
"
data
"
,
blobs
[
0
]);
return
putFullDoc
(
jio
,
"
doc
"
,
docs
[
0
],
"
data
"
,
blobs
[
0
]);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
// 3,4
return
putFullDoc
(
jio
,
"
second_doc
"
,
docs
[
1
],
"
data
"
,
blobs
[
1
]);
return
putFullDoc
(
jio
,
"
second_doc
"
,
docs
[
1
],
"
data
"
,
blobs
[
1
]);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
...
@@ -1119,15 +1381,25 @@
...
@@ -1119,15 +1381,25 @@
docs
[
1
].
date
=
4
;
docs
[
1
].
date
=
4
;
docs
[
1
].
type
=
"
bar2
"
;
docs
[
1
].
type
=
"
bar2
"
;
})
})
.
push
(
function
()
{
.
push
(
function
()
{
// 5,6
return
putFullDoc
(
jio
,
"
doc
"
,
docs
[
0
],
"
data
"
,
blobs
[
2
]);
return
putFullDoc
(
jio
,
"
doc
"
,
docs
[
0
],
"
data
"
,
blobs
[
2
]);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
// 7
return
jio
.
remove
(
"
second_doc
"
);
return
jio
.
remove
(
"
second_doc
"
);
})
})
.
push
(
function
()
{
.
push
(
function
()
{
// 8,9
return
putFullDoc
(
jio
,
"
second_doc
"
,
docs
[
1
],
"
data
"
,
blobs
[
3
]);
return
putFullDoc
(
jio
,
"
second_doc
"
,
docs
[
1
],
"
data
"
,
blobs
[
3
]);
})
})
.
push
(
function
()
{
return
not_history
.
allDocs
({
sort_on
:
[[
"
timestamp
"
,
"
ascending
"
]]
});
})
.
push
(
function
(
results
)
{
timestamps
=
results
.
data
.
rows
.
map
(
function
(
d
)
{
return
d
.
id
;
});
})
.
push
(
function
()
{
.
push
(
function
()
{
return
not_history
.
allDocs
({
return
not_history
.
allDocs
({
sort_on
:
[[
"
timestamp
"
,
"
descending
"
]],
sort_on
:
[[
"
timestamp
"
,
"
descending
"
]],
...
@@ -1138,92 +1410,92 @@
...
@@ -1138,92 +1410,92 @@
deepEqual
(
results
.
data
.
rows
,
[
deepEqual
(
results
.
data
.
rows
,
[
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
second_doc
.
data
[
1
],
id
:
timestamps
[
9
],
value
:
{
value
:
{
"
op
"
:
"
putAttachment
"
,
"
op
"
:
"
putAttachment
"
,
"
doc_id
"
:
"
second_doc
"
,
"
doc_id
"
:
"
second_doc
"
,
"
timestamp
"
:
timestamps
.
second_doc
.
data
[
1
]
"
timestamp
"
:
timestamps
[
9
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
second_doc
[
2
],
id
:
timestamps
[
8
],
value
:
{
value
:
{
"
op
"
:
"
put
"
,
"
op
"
:
"
put
"
,
"
doc_id
"
:
"
second_doc
"
,
"
doc_id
"
:
"
second_doc
"
,
"
timestamp
"
:
timestamps
.
second_doc
[
2
]
"
timestamp
"
:
timestamps
[
8
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
second_doc
[
1
],
id
:
timestamps
[
7
],
value
:
{
value
:
{
"
op
"
:
"
remove
"
,
"
op
"
:
"
remove
"
,
"
doc_id
"
:
"
second_doc
"
,
"
doc_id
"
:
"
second_doc
"
,
"
timestamp
"
:
timestamps
.
second_doc
[
1
]
"
timestamp
"
:
timestamps
[
7
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
doc
.
data
[
1
],
id
:
timestamps
[
6
],
value
:
{
value
:
{
"
op
"
:
"
putAttachment
"
,
"
op
"
:
"
putAttachment
"
,
"
doc_id
"
:
"
doc
"
,
"
doc_id
"
:
"
doc
"
,
"
timestamp
"
:
timestamps
.
doc
.
data
[
1
]
"
timestamp
"
:
timestamps
[
6
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
doc
[
2
],
id
:
timestamps
[
5
],
value
:
{
value
:
{
"
op
"
:
"
put
"
,
"
op
"
:
"
put
"
,
"
doc_id
"
:
"
doc
"
,
"
doc_id
"
:
"
doc
"
,
"
timestamp
"
:
timestamps
.
doc
[
2
]
"
timestamp
"
:
timestamps
[
5
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
second_doc
.
data
[
0
],
id
:
timestamps
[
4
],
value
:
{
value
:
{
"
op
"
:
"
putAttachment
"
,
"
op
"
:
"
putAttachment
"
,
"
doc_id
"
:
"
second_doc
"
,
"
doc_id
"
:
"
second_doc
"
,
"
timestamp
"
:
timestamps
.
second_doc
.
data
[
0
]
"
timestamp
"
:
timestamps
[
4
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
second_doc
[
0
],
id
:
timestamps
[
3
],
value
:
{
value
:
{
"
op
"
:
"
put
"
,
"
op
"
:
"
put
"
,
"
doc_id
"
:
"
second_doc
"
,
"
doc_id
"
:
"
second_doc
"
,
"
timestamp
"
:
timestamps
.
second_doc
[
0
]
"
timestamp
"
:
timestamps
[
3
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
doc
.
data
[
0
],
id
:
timestamps
[
2
],
value
:
{
value
:
{
"
op
"
:
"
putAttachment
"
,
"
op
"
:
"
putAttachment
"
,
"
doc_id
"
:
"
doc
"
,
"
doc_id
"
:
"
doc
"
,
"
timestamp
"
:
timestamps
.
doc
.
data
[
0
]
"
timestamp
"
:
timestamps
[
2
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
doc
[
1
],
id
:
timestamps
[
1
],
value
:
{
value
:
{
"
op
"
:
"
put
"
,
"
op
"
:
"
put
"
,
"
doc_id
"
:
"
doc
"
,
"
doc_id
"
:
"
doc
"
,
"
timestamp
"
:
timestamps
.
doc
[
1
]
"
timestamp
"
:
timestamps
[
1
]
}
}
},
},
{
{
doc
:
{},
doc
:
{},
id
:
timestamps
.
doc
[
0
],
id
:
timestamps
[
0
],
value
:
{
value
:
{
"
op
"
:
"
put
"
,
"
op
"
:
"
put
"
,
"
doc_id
"
:
"
doc
"
,
"
doc_id
"
:
"
doc
"
,
"
timestamp
"
:
timestamps
.
doc
[
0
]
"
timestamp
"
:
timestamps
[
0
]
}
}
}
}
],
"
All operations are logged correctly
"
);
],
"
All operations are logged correctly
"
);
...
@@ -1269,14 +1541,13 @@
...
@@ -1269,14 +1541,13 @@
})
})
.
push
(
function
()
{
.
push
(
function
()
{
return
jio
.
allDocs
({
return
jio
.
allDocs
({
query
:
"
(_timestamp: >=
"
+
timestamps
.
second_doc
[
0
]
+
query
:
"
NOT (date: >= 2 AND date: <= 3)
"
,
"
OR _timestamp: <=
"
+
timestamps
.
doc
[
1
]
+
"
) AND NOT (date: = 2)
"
,
select_list
:
[
"
date
"
,
"
non-existent-key
"
,
"
type
"
,
"
title
"
],
select_list
:
[
"
date
"
,
"
non-existent-key
"
,
"
type
"
,
"
title
"
],
sort_on
:
[[
"
date
"
,
"
descending
"
],
sort_on
:
[[
"
date
"
,
"
descending
"
],
[
"
non-existent-key
"
,
"
ascending
"
],
[
"
non-existent-key
"
,
"
ascending
"
],
[
"
_timestamp
"
,
"
ascending
"
]
[
"
_timestamp
"
,
"
ascending
"
]
]
],
include_revisions
:
true
});
});
})
})
.
push
(
function
(
results
)
{
.
push
(
function
(
results
)
{
...
@@ -1288,7 +1559,8 @@
...
@@ -1288,7 +1559,8 @@
date
:
4
,
date
:
4
,
title
:
"
doc
"
,
title
:
"
doc
"
,
type
:
"
foo2
"
type
:
"
foo2
"
}
},
timestamp
:
timestamps
[
5
]
},
},
{
{
doc
:
{},
doc
:
{},
...
@@ -1297,7 +1569,8 @@
...
@@ -1297,7 +1569,8 @@
date
:
4
,
date
:
4
,
title
:
"
second_doc
"
,
title
:
"
second_doc
"
,
type
:
"
bar2
"
type
:
"
bar2
"
}
},
timestamp
:
timestamps
[
8
]
},
},
{
{
doc
:
{},
doc
:
{},
...
@@ -1306,12 +1579,14 @@
...
@@ -1306,12 +1579,14 @@
date
:
1
,
date
:
1
,
title
:
"
doc
"
,
title
:
"
doc
"
,
type
:
"
foo
"
type
:
"
foo
"
}
},
timestamp
:
timestamps
[
1
]
},
},
{
{
doc
:
{},
doc
:
{},
id
:
"
doc
"
,
id
:
"
doc
"
,
value
:
{}
value
:
{},
timestamp
:
timestamps
[
0
]
}
}
],
],
"
Query gives correct results in correct order
"
);
"
Query gives correct results in correct order
"
);
...
...
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