You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@couchdb.apache.org by GitBox <gi...@apache.org> on 2022/09/22 04:07:24 UTC
[GitHub] [couchdb] nickva opened a new pull request, #4185: Add couch_db:open_doc_revs/3
nickva opened a new pull request, #4185:
URL: https://github.com/apache/couchdb/pull/4185
**_This is a draft PR for now. Will need to add a few tests for it before it is ready_**
This is the companion to open_doc_revs/4 which operates on a batch of docs at a time. As a lucky coincidence, the internal open_doc_revs_int/3 function already operates on batches, so we just expose the batched variant.
This function will be the used to optimize the _bulk_get implementation as described in issue https://github.com/apache/couchdb/issues/4183. To allow incremental node updates, let's have the backend implementation in a separate commit so it could be included in separate rolling updates releases.
Issue: https://github.com/apache/couchdb/issues/4183
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [couchdb] jaydoane commented on a diff in pull request #4185: Expose the batched open_doc_revs function variant
Posted by GitBox <gi...@apache.org>.
jaydoane commented on code in PR #4185:
URL: https://github.com/apache/couchdb/pull/4185#discussion_r980312548
##########
src/couch/test/eunit/couchdb_open_doc_revs_tests.erl:
##########
@@ -0,0 +1,214 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(couchdb_open_doc_revs_tests).
+
+-include_lib("couch/include/couch_eunit.hrl").
+-include_lib("couch/include/couch_db.hrl").
+
+-define(TDEF_FE(Name), fun(Arg) -> {atom_to_list(Name), ?_test(Name(Arg))} end).
+
+open_doc_revs_test_() ->
+ {
+ foreach,
+ fun setup/0,
+ fun teardown/1,
+ [
+ ?TDEF_FE(open_doc_revs_single),
+ ?TDEF_FE(open_doc_revs_batch)
+ ]
+ }.
+
+setup() ->
+ Ctx = test_util:start_couch(),
+ DbName = ?tempdb(),
+ {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]),
+ Docs = [
+ doc(<<"1">>, [<<"z">>]),
+ doc(<<"1">>, [<<"x">>, <<"z">>]),
+ doc(<<"1">>, [<<"y">>, <<"z">>]),
+ doc(<<"1">>, [<<"w">>, <<"y">>, <<"z">>]),
+
+ doc(<<"2">>, [<<"m">>]),
+ doc(<<"2">>, [<<"l">>, <<"k">>], true)
+ ],
+ {ok, []} = couch_db:update_docs(Db, Docs, [], ?REPLICATED_CHANGES),
+ ok = couch_db:close(Db),
+ {Ctx, DbName}.
+
+teardown({Ctx, DbName}) ->
+ ok = couch_server:delete(DbName, [?ADMIN_CTX]),
+ test_util:stop_couch(Ctx).
+
+open_doc_revs_single({_, DbName}) ->
+ {ok, Db} = couch_db:open_int(DbName, []),
+
+ % Empty revs list
+ ?assertEqual({ok, []}, couch_db:open_doc_revs(Db, <<"1">>, [], [])),
+
+ % Missing rev
+ ?assertMatch(
+ {ok, [{{not_found, missing}, _}]},
+ couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"foo">>}], [])
+ ),
+
+ % Missing doc
+ ?assertMatch(
+ {ok, [{{not_found, missing}, _}]},
+ couch_db:open_doc_revs(Db, <<"foo">>, [{1, <<"bar">>}], [])
+ ),
+
+ % All revs option
+ {ok, Res1} = couch_db:open_doc_revs(Db, <<"1">>, all, []),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res1
+ ),
+
+ % Basic revs fetch
+ {ok, Res2} = couch_db:open_doc_revs(Db, <<"1">>, [{2, <<"x">>}], []),
+ ?assertMatch([{ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}}], Res2),
+
+ % Fetch a revision that's not the latest
+ {ok, Res3} = couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"z">>}], []),
+ ?assertMatch([{ok, #doc{revs = {1, [<<"z">>]}}}], Res3),
+
+ % Force latest revision fetchs, since it's a conflict we get 2
+ % revisions back. They are both "latest".
+ {ok, Res4} = couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"z">>}], [latest]),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res4
+ ),
+
+ % Latest option wiht rev from a single branch so we get only one
Review Comment:
s/wiht/with/
##########
src/couch/test/eunit/couchdb_open_doc_revs_tests.erl:
##########
@@ -0,0 +1,214 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(couchdb_open_doc_revs_tests).
+
+-include_lib("couch/include/couch_eunit.hrl").
+-include_lib("couch/include/couch_db.hrl").
+
+-define(TDEF_FE(Name), fun(Arg) -> {atom_to_list(Name), ?_test(Name(Arg))} end).
+
+open_doc_revs_test_() ->
+ {
+ foreach,
+ fun setup/0,
+ fun teardown/1,
+ [
+ ?TDEF_FE(open_doc_revs_single),
+ ?TDEF_FE(open_doc_revs_batch)
+ ]
+ }.
+
+setup() ->
+ Ctx = test_util:start_couch(),
+ DbName = ?tempdb(),
+ {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]),
+ Docs = [
+ doc(<<"1">>, [<<"z">>]),
+ doc(<<"1">>, [<<"x">>, <<"z">>]),
+ doc(<<"1">>, [<<"y">>, <<"z">>]),
+ doc(<<"1">>, [<<"w">>, <<"y">>, <<"z">>]),
+
+ doc(<<"2">>, [<<"m">>]),
+ doc(<<"2">>, [<<"l">>, <<"k">>], true)
+ ],
+ {ok, []} = couch_db:update_docs(Db, Docs, [], ?REPLICATED_CHANGES),
+ ok = couch_db:close(Db),
+ {Ctx, DbName}.
+
+teardown({Ctx, DbName}) ->
+ ok = couch_server:delete(DbName, [?ADMIN_CTX]),
+ test_util:stop_couch(Ctx).
+
+open_doc_revs_single({_, DbName}) ->
+ {ok, Db} = couch_db:open_int(DbName, []),
+
+ % Empty revs list
+ ?assertEqual({ok, []}, couch_db:open_doc_revs(Db, <<"1">>, [], [])),
+
+ % Missing rev
+ ?assertMatch(
+ {ok, [{{not_found, missing}, _}]},
+ couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"foo">>}], [])
+ ),
+
+ % Missing doc
+ ?assertMatch(
+ {ok, [{{not_found, missing}, _}]},
+ couch_db:open_doc_revs(Db, <<"foo">>, [{1, <<"bar">>}], [])
+ ),
+
+ % All revs option
+ {ok, Res1} = couch_db:open_doc_revs(Db, <<"1">>, all, []),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res1
+ ),
+
+ % Basic revs fetch
+ {ok, Res2} = couch_db:open_doc_revs(Db, <<"1">>, [{2, <<"x">>}], []),
+ ?assertMatch([{ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}}], Res2),
+
+ % Fetch a revision that's not the latest
+ {ok, Res3} = couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"z">>}], []),
+ ?assertMatch([{ok, #doc{revs = {1, [<<"z">>]}}}], Res3),
+
+ % Force latest revision fetchs, since it's a conflict we get 2
+ % revisions back. They are both "latest".
+ {ok, Res4} = couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"z">>}], [latest]),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res4
+ ),
+
+ % Latest option wiht rev from a single branch so we get only one
+ % result back.
+ {ok, Res5} = couch_db:open_doc_revs(Db, <<"1">>, [{2, <<"y">>}], [latest]),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res5
+ ),
+
+ % Make sure deleted revisions are also returned
+ {ok, Res6} = couch_db:open_doc_revs(Db, <<"2">>, all, []),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {1, [<<"m">>]}}},
+ {ok, #doc{revs = {2, [<<"l">>, <<"k">>]}, deleted = true}}
+ ],
+ Res6
+ ).
+
+open_doc_revs_batch({_, DbName}) ->
+ {ok, Db} = couch_db:open_int(DbName, []),
+
+ % Empty batch
+ ?assertEqual([], couch_db:open_doc_revs(Db, [], [])),
+
+ % One doc, empty list of revisions
+ ?assertEqual(
+ [[]],
+ couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, []}, []}
+ ],
+ []
+ )
+ ),
+
+ % Multiple results. Some found, some not found
+ ?assertMatch(
+ [
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ [
+ {{not_found, _}, _}
+ ],
+ [
+ {{not_found, _}, _}
+ ]
+ ],
+ couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, all}, []},
+ {{<<"1">>, [{1, <<"foo">>}]}, []},
+ {{<<"foo">>, [{1, <<"bar">>}]}, []}
+ ],
+ []
+ )
+ ),
+
+ % Fetch the exact same doc and revisions
+ ?assertMatch(
+ [
+ [
+ {ok, #doc{revs = {2, [<<"y">>, <<"z">>]}}}
+ ],
+ [
+ {ok, #doc{revs = {2, [<<"y">>, <<"z">>]}}}
+ ]
+ ],
+ couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, [{2, <<"y">>}]}, []},
+ {{<<"1">>, [{2, <<"y">>}]}, []}
+ ],
+ []
+ )
+ ),
+
+ % Make sure individual doc options are applied
+ [[{ok, Doc1}], [{ok, Doc2}]] = couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, [{2, <<"y">>}]}, [{atts_since, [{2, <<"y">>}]}]},
+ {{<<"1">>, [{2, <<"y">>}]}, []}
+ ],
+ []
+ ),
+ [Att1] = Doc1#doc.atts,
+ [Att2] = Doc2#doc.atts,
+ ?assertEqual(stub, couch_att:fetch(data, Att1)),
+ ?assertMatch({stream, _}, couch_att:fetch(data, Att2)).
Review Comment:
Can you maybe explain in a comment why `stub` and `{stream, _}` are the expected results here?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [couchdb] nickva commented on a diff in pull request #4185: Expose the batched open_doc_revs function variant
Posted by GitBox <gi...@apache.org>.
nickva commented on code in PR #4185:
URL: https://github.com/apache/couchdb/pull/4185#discussion_r980410431
##########
src/couch/test/eunit/couchdb_open_doc_revs_tests.erl:
##########
@@ -0,0 +1,214 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(couchdb_open_doc_revs_tests).
+
+-include_lib("couch/include/couch_eunit.hrl").
+-include_lib("couch/include/couch_db.hrl").
+
+-define(TDEF_FE(Name), fun(Arg) -> {atom_to_list(Name), ?_test(Name(Arg))} end).
+
+open_doc_revs_test_() ->
+ {
+ foreach,
+ fun setup/0,
+ fun teardown/1,
+ [
+ ?TDEF_FE(open_doc_revs_single),
+ ?TDEF_FE(open_doc_revs_batch)
+ ]
+ }.
+
+setup() ->
+ Ctx = test_util:start_couch(),
+ DbName = ?tempdb(),
+ {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]),
+ Docs = [
+ doc(<<"1">>, [<<"z">>]),
+ doc(<<"1">>, [<<"x">>, <<"z">>]),
+ doc(<<"1">>, [<<"y">>, <<"z">>]),
+ doc(<<"1">>, [<<"w">>, <<"y">>, <<"z">>]),
+
+ doc(<<"2">>, [<<"m">>]),
+ doc(<<"2">>, [<<"l">>, <<"k">>], true)
+ ],
+ {ok, []} = couch_db:update_docs(Db, Docs, [], ?REPLICATED_CHANGES),
+ ok = couch_db:close(Db),
+ {Ctx, DbName}.
+
+teardown({Ctx, DbName}) ->
+ ok = couch_server:delete(DbName, [?ADMIN_CTX]),
+ test_util:stop_couch(Ctx).
+
+open_doc_revs_single({_, DbName}) ->
+ {ok, Db} = couch_db:open_int(DbName, []),
+
+ % Empty revs list
+ ?assertEqual({ok, []}, couch_db:open_doc_revs(Db, <<"1">>, [], [])),
+
+ % Missing rev
+ ?assertMatch(
+ {ok, [{{not_found, missing}, _}]},
+ couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"foo">>}], [])
+ ),
+
+ % Missing doc
+ ?assertMatch(
+ {ok, [{{not_found, missing}, _}]},
+ couch_db:open_doc_revs(Db, <<"foo">>, [{1, <<"bar">>}], [])
+ ),
+
+ % All revs option
+ {ok, Res1} = couch_db:open_doc_revs(Db, <<"1">>, all, []),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res1
+ ),
+
+ % Basic revs fetch
+ {ok, Res2} = couch_db:open_doc_revs(Db, <<"1">>, [{2, <<"x">>}], []),
+ ?assertMatch([{ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}}], Res2),
+
+ % Fetch a revision that's not the latest
+ {ok, Res3} = couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"z">>}], []),
+ ?assertMatch([{ok, #doc{revs = {1, [<<"z">>]}}}], Res3),
+
+ % Force latest revision fetchs, since it's a conflict we get 2
+ % revisions back. They are both "latest".
+ {ok, Res4} = couch_db:open_doc_revs(Db, <<"1">>, [{1, <<"z">>}], [latest]),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res4
+ ),
+
+ % Latest option wiht rev from a single branch so we get only one
+ % result back.
+ {ok, Res5} = couch_db:open_doc_revs(Db, <<"1">>, [{2, <<"y">>}], [latest]),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ Res5
+ ),
+
+ % Make sure deleted revisions are also returned
+ {ok, Res6} = couch_db:open_doc_revs(Db, <<"2">>, all, []),
+ ?assertMatch(
+ [
+ {ok, #doc{revs = {1, [<<"m">>]}}},
+ {ok, #doc{revs = {2, [<<"l">>, <<"k">>]}, deleted = true}}
+ ],
+ Res6
+ ).
+
+open_doc_revs_batch({_, DbName}) ->
+ {ok, Db} = couch_db:open_int(DbName, []),
+
+ % Empty batch
+ ?assertEqual([], couch_db:open_doc_revs(Db, [], [])),
+
+ % One doc, empty list of revisions
+ ?assertEqual(
+ [[]],
+ couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, []}, []}
+ ],
+ []
+ )
+ ),
+
+ % Multiple results. Some found, some not found
+ ?assertMatch(
+ [
+ [
+ {ok, #doc{revs = {2, [<<"x">>, <<"z">>]}}},
+ {ok, #doc{revs = {3, [<<"w">>, <<"y">>, <<"z">>]}}}
+ ],
+ [
+ {{not_found, _}, _}
+ ],
+ [
+ {{not_found, _}, _}
+ ]
+ ],
+ couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, all}, []},
+ {{<<"1">>, [{1, <<"foo">>}]}, []},
+ {{<<"foo">>, [{1, <<"bar">>}]}, []}
+ ],
+ []
+ )
+ ),
+
+ % Fetch the exact same doc and revisions
+ ?assertMatch(
+ [
+ [
+ {ok, #doc{revs = {2, [<<"y">>, <<"z">>]}}}
+ ],
+ [
+ {ok, #doc{revs = {2, [<<"y">>, <<"z">>]}}}
+ ]
+ ],
+ couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, [{2, <<"y">>}]}, []},
+ {{<<"1">>, [{2, <<"y">>}]}, []}
+ ],
+ []
+ )
+ ),
+
+ % Make sure individual doc options are applied
+ [[{ok, Doc1}], [{ok, Doc2}]] = couch_db:open_doc_revs(
+ Db,
+ [
+ {{<<"1">>, [{2, <<"y">>}]}, [{atts_since, [{2, <<"y">>}]}]},
+ {{<<"1">>, [{2, <<"y">>}]}, []}
+ ],
+ []
+ ),
+ [Att1] = Doc1#doc.atts,
+ [Att2] = Doc2#doc.atts,
+ ?assertEqual(stub, couch_att:fetch(data, Att1)),
+ ?assertMatch({stream, _}, couch_att:fetch(data, Att2)).
Review Comment:
Good idea. Will do
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [couchdb] nickva merged pull request #4185: Expose the batched open_doc_revs function variant
Posted by GitBox <gi...@apache.org>.
nickva merged PR #4185:
URL: https://github.com/apache/couchdb/pull/4185
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@couchdb.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org