summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2009-08-12 03:20:21 +0000
committerJohn Christopher Anderson <jchris@apache.org>2009-08-12 03:20:21 +0000
commitdc665a05644774f232718dd7c35dd1aac34f389e (patch)
treecb57fa6deaaf3f268f0b47573bbcbb9cf178be59
parentd726977bfa8d73ac8928c5379dd5b5c50ae2c38f (diff)
recloses COUCHDB-4 (view etags) thanks to Matt Goodall for the tests. keep 'em coming!
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@803358 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--share/www/script/test/etags_views.js17
-rw-r--r--src/couchdb/couch_httpd_db.erl4
-rw-r--r--src/couchdb/couch_httpd_show.erl8
-rw-r--r--src/couchdb/couch_httpd_view.erl25
4 files changed, 36 insertions, 18 deletions
diff --git a/share/www/script/test/etags_views.js b/share/www/script/test/etags_views.js
index 3d8b63b7..a33317d9 100644
--- a/share/www/script/test/etags_views.js
+++ b/share/www/script/test/etags_views.js
@@ -83,4 +83,21 @@ couchTests.etags_views = function(debug) {
// list etag
// in the list test for now
+
+ // A new database should have unique _all_docs etags.
+ db.deleteDb();
+ db.createDb();
+ db.save({a: 1});
+ xhr = CouchDB.request("GET", "/test_suite_db/_all_docs");
+ var etag = xhr.getResponseHeader("etag");
+ db.deleteDb();
+ db.createDb();
+ db.save({a: 2});
+ xhr = CouchDB.request("GET", "/test_suite_db/_all_docs");
+ var new_etag = xhr.getResponseHeader("etag");
+ T(etag != new_etag);
+ // but still be cacheable
+ xhr = CouchDB.request("GET", "/test_suite_db/_all_docs");
+ T(new_etag == xhr.getResponseHeader("etag"));
+
};
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index 119182af..159bcbe8 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -406,7 +406,7 @@ db_req(#httpd{method='GET',path_parts=[_,<<"_all_docs_by_seq">>]}=Req, Db) ->
} = QueryArgs = couch_httpd_view:parse_view_params(Req, nil, map),
{ok, Info} = couch_db:get_db_info(Db),
- CurrentEtag = couch_httpd:make_etag(proplists:get_value(update_seq, Info)),
+ CurrentEtag = couch_httpd:make_etag(Info),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
TotalRowCount = proplists:get_value(doc_count, Info),
FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db,
@@ -521,7 +521,7 @@ all_docs_view(Req, Db, Keys) ->
direction = Dir
} = QueryArgs = couch_httpd_view:parse_view_params(Req, Keys, map),
{ok, Info} = couch_db:get_db_info(Db),
- CurrentEtag = couch_httpd:make_etag(proplists:get_value(update_seq, Info)),
+ CurrentEtag = couch_httpd:make_etag(Info),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
TotalRowCount = proplists:get_value(doc_count, Info),
diff --git a/src/couchdb/couch_httpd_show.erl b/src/couchdb/couch_httpd_show.erl
index 27fd9703..294acbac 100644
--- a/src/couchdb/couch_httpd_show.erl
+++ b/src/couchdb/couch_httpd_show.erl
@@ -164,7 +164,7 @@ output_map_list(#httpd{mochi_req=MReq, user_ctx=UserCtx}=Req, Lang, ListSrc, Vie
Headers = MReq:get(headers),
Hlist = mochiweb_headers:to_list(Headers),
Accept = proplists:get_value('Accept', Hlist),
- CurrentEtag = couch_httpd_view:view_group_etag(Group, {Lang, ListSrc, Accept, UserCtx}),
+ CurrentEtag = couch_httpd_view:view_group_etag(Group, Db, {Lang, ListSrc, Accept, UserCtx}),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
% get the os process here
% pass it into the view fold with closures
@@ -195,7 +195,7 @@ output_map_list(#httpd{mochi_req=MReq, user_ctx=UserCtx}=Req, Lang, ListSrc, Vie
Headers = MReq:get(headers),
Hlist = mochiweb_headers:to_list(Headers),
Accept = proplists:get_value('Accept', Hlist),
- CurrentEtag = couch_httpd_view:view_group_etag(Group, {Lang, ListSrc, Accept, UserCtx}),
+ CurrentEtag = couch_httpd_view:view_group_etag(Group, Db, {Lang, ListSrc, Accept, UserCtx}),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
% get the os process here
% pass it into the view fold with closures
@@ -295,7 +295,7 @@ output_reduce_list(#httpd{mochi_req=MReq, user_ctx=UserCtx}=Req, Lang, ListSrc,
Headers = MReq:get(headers),
Hlist = mochiweb_headers:to_list(Headers),
Accept = proplists:get_value('Accept', Hlist),
- CurrentEtag = couch_httpd_view:view_group_etag(Group, {Lang, ListSrc, Accept, UserCtx}),
+ CurrentEtag = couch_httpd_view:view_group_etag(Group, Db, {Lang, ListSrc, Accept, UserCtx}),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
StartListRespFun = make_reduce_start_resp_fun(QueryServer, Req, Db, CurrentEtag),
SendListRowFun = make_reduce_send_row_fun(QueryServer, Db),
@@ -328,7 +328,7 @@ output_reduce_list(#httpd{mochi_req=MReq, user_ctx=UserCtx}=Req, Lang, ListSrc,
Headers = MReq:get(headers),
Hlist = mochiweb_headers:to_list(Headers),
Accept = proplists:get_value('Accept', Hlist),
- CurrentEtag = couch_httpd_view:view_group_etag(Group, {Lang, ListSrc, Accept, UserCtx, Keys}),
+ CurrentEtag = couch_httpd_view:view_group_etag(Group, Db, {Lang, ListSrc, Accept, UserCtx, Keys}),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
StartListRespFun = make_reduce_start_resp_fun(QueryServer, Req, Db, CurrentEtag),
diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl
index 2aa7d626..8264186b 100644
--- a/src/couchdb/couch_httpd_view.erl
+++ b/src/couchdb/couch_httpd_view.erl
@@ -17,7 +17,7 @@
-export([get_stale_type/1, get_reduce_type/1, parse_view_params/3]).
-export([make_view_fold_fun/6, finish_view_fold/3, view_row_obj/3]).
--export([view_group_etag/1, view_group_etag/2, make_reduce_fold_funs/5]).
+-export([view_group_etag/2, view_group_etag/3, make_reduce_fold_funs/5]).
-export([design_doc_view/5, parse_bool_param/1]).
-import(couch_httpd,
@@ -43,7 +43,7 @@ design_doc_view(Req, Db, Id, ViewName, Keys) ->
output_map_view(Req, MapView, Group, Db, QueryArgs, Keys);
_ ->
QueryArgs = parse_view_params(Req, Keys, reduce),
- output_reduce_view(Req, ReduceView, Group, QueryArgs, Keys)
+ output_reduce_view(Req, Db, ReduceView, Group, QueryArgs, Keys)
end;
_ ->
throw({not_found, Reason})
@@ -133,7 +133,7 @@ handle_temp_view_req(#httpd{method='POST'}=Req, Db) ->
QueryArgs = parse_view_params(Req, Keys, reduce),
{ok, View, Group} = couch_view:get_temp_reduce_view(Db, Language,
DesignOptions, MapSrc, RedSrc),
- output_reduce_view(Req, View, Group, QueryArgs, Keys)
+ output_reduce_view(Req, Db, View, Group, QueryArgs, Keys)
end;
handle_temp_view_req(Req, _Db) ->
@@ -147,7 +147,7 @@ output_map_view(Req, View, Group, Db, QueryArgs, nil) ->
start_key = StartKey,
start_docid = StartDocId
} = QueryArgs,
- CurrentEtag = view_group_etag(Group),
+ CurrentEtag = view_group_etag(Group, Db),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
{ok, RowCount} = couch_view:get_row_count(View),
Start = {StartKey, StartDocId},
@@ -164,7 +164,7 @@ output_map_view(Req, View, Group, Db, QueryArgs, Keys) ->
skip = SkipCount,
start_docid = StartDocId
} = QueryArgs,
- CurrentEtag = view_group_etag(Group, Keys),
+ CurrentEtag = view_group_etag(Group, Db, Keys),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
{ok, RowCount} = couch_view:get_row_count(View),
FoldAccInit = {Limit, SkipCount, undefined, [], nil},
@@ -184,7 +184,7 @@ output_map_view(Req, View, Group, Db, QueryArgs, Keys) ->
finish_view_fold(Req, RowCount, FoldResult)
end).
-output_reduce_view(Req, View, Group, QueryArgs, nil) ->
+output_reduce_view(Req, Db, View, Group, QueryArgs, nil) ->
#view_query_args{
start_key = StartKey,
end_key = EndKey,
@@ -195,7 +195,7 @@ output_reduce_view(Req, View, Group, QueryArgs, nil) ->
end_docid = EndDocId,
group_level = GroupLevel
} = QueryArgs,
- CurrentEtag = view_group_etag(Group),
+ CurrentEtag = view_group_etag(Group, Db),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
{ok, GroupRowsFun, RespFun} = make_reduce_fold_funs(Req, GroupLevel, QueryArgs, CurrentEtag, #reduce_fold_helper_funs{}),
FoldAccInit = {Limit, Skip, undefined, []},
@@ -204,7 +204,7 @@ output_reduce_view(Req, View, Group, QueryArgs, nil) ->
finish_reduce_fold(Req, Resp)
end);
-output_reduce_view(Req, View, Group, QueryArgs, Keys) ->
+output_reduce_view(Req, Db, View, Group, QueryArgs, Keys) ->
#view_query_args{
limit = Limit,
skip = Skip,
@@ -213,7 +213,7 @@ output_reduce_view(Req, View, Group, QueryArgs, Keys) ->
end_docid = EndDocId,
group_level = GroupLevel
} = QueryArgs,
- CurrentEtag = view_group_etag(Group),
+ CurrentEtag = view_group_etag(Group, Db),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
{ok, GroupRowsFun, RespFun} = make_reduce_fold_funs(Req, GroupLevel, QueryArgs, CurrentEtag, #reduce_fold_helper_funs{}),
{Resp, _RedAcc3} = lists:foldl(
@@ -608,10 +608,11 @@ send_json_reduce_row(Resp, {Key, Value}, RowFront) ->
send_chunk(Resp, RowFront ++ ?JSON_ENCODE({[{key, Key}, {value, Value}]})),
{ok, ",\r\n"}.
-view_group_etag(Group) ->
- view_group_etag(Group, nil).
+view_group_etag(Group, Db) ->
+ view_group_etag(Group, Db, nil).
-view_group_etag(#group{sig=Sig,current_seq=CurrentSeq}, Extra) ->
+view_group_etag(#group{sig=Sig,current_seq=CurrentSeq}, Db, Extra) ->
+ % ?LOG_ERROR("Group ~p",[Group]),
% This is not as granular as it could be.
% If there are updates to the db that do not effect the view index,
% they will change the Etag. For more granular Etags we'd need to keep