summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@apache.org>2020-09-01 15:28:25 -0400
committerNick Vatamaniuc <vatamane@apache.org>2020-09-01 16:29:49 -0400
commit5d2af3563b1c3784d289b2f91f202a0bf5ce750d (patch)
treec0ac6f2ce6cb26e9c6ddb0316d6c76518278c9df
parentbf61a0051f6a0ae88cc40b7e6cd7710033fef33f (diff)
downloadcouchdb-allow-creating-new-deleted-documents.tar.gz
Allow creating new deleted documentsallow-creating-new-deleted-documents
This makes it compatible with CouchDB <= 3.x where we can create deleted documents. How to check: ``` $ http put $DB1/mydb $ http put $DB1/mydb/foo _deleted:='true' a=b { "id": "foo", "ok": true, "rev": "1-ad7eb689fcae75e7a7edb57dc1f30939" } ```
-rw-r--r--src/fabric/src/fabric2_db.erl11
-rw-r--r--src/fabric/test/fabric2_doc_crud_tests.erl12
2 files changed, 17 insertions, 6 deletions
diff --git a/src/fabric/src/fabric2_db.erl b/src/fabric/src/fabric2_db.erl
index 4ac105589..b62f26ec8 100644
--- a/src/fabric/src/fabric2_db.erl
+++ b/src/fabric/src/fabric2_db.erl
@@ -1831,13 +1831,16 @@ update_doc_interactive(Db, Doc0, Future, _Options) ->
% Check that a revision was specified if required
Doc0RevId = doc_to_revid(Doc0),
- if Doc0RevId /= {0, <<>>} orelse WinnerRevId == {0, <<>>} -> ok; true ->
+ HasRev = Doc0RevId =/= {0, <<>>},
+ if HasRev orelse WinnerRevId == {0, <<>>} -> ok; true ->
?RETURN({Doc0, conflict})
end,
- % Check that we're not trying to create a deleted doc
- if Doc0RevId /= {0, <<>>} orelse not Doc0#doc.deleted -> ok; true ->
- ?RETURN({Doc0, conflict})
+ % Allow inserting new deleted documents. Only works when the document has
+ % never existed to match CouchDB 3.x
+ case not HasRev andalso Doc0#doc.deleted andalso is_map(Winner) of
+ true -> ?RETURN({Doc0, conflict});
+ false -> ok
end,
% Get the target revision to update
diff --git a/src/fabric/test/fabric2_doc_crud_tests.erl b/src/fabric/test/fabric2_doc_crud_tests.erl
index ce3757d55..7a24b7d52 100644
--- a/src/fabric/test/fabric2_doc_crud_tests.erl
+++ b/src/fabric/test/fabric2_doc_crud_tests.erl
@@ -49,7 +49,7 @@ doc_crud_test_() ->
?TDEF(recreate_doc_basic),
?TDEF(conflict_on_create_new_with_rev),
?TDEF(conflict_on_update_with_no_rev),
- ?TDEF(conflict_on_create_as_deleted),
+ ?TDEF(allow_create_new_as_deleted),
?TDEF(conflict_on_recreate_as_deleted),
?TDEF(conflict_on_extend_deleted),
?TDEF(open_doc_revs_basic),
@@ -449,12 +449,20 @@ conflict_on_update_with_no_rev({Db, _}) ->
?assertThrow(conflict, fabric2_db:update_doc(Db, Doc2)).
-conflict_on_create_as_deleted({Db, _}) ->
+allow_create_new_as_deleted({Db, _}) ->
Doc = #doc{
id = fabric2_util:uuid(),
deleted = true,
body = {[{<<"foo">>, <<"bar">>}]}
},
+ {ok, {1, Rev}} = fabric2_db:update_doc(Db, Doc),
+ ?assertEqual({not_found, deleted}, fabric2_db:open_doc(Db, Doc#doc.id)),
+ Doc1 = Doc#doc{
+ revs = {1, [Rev]}
+ },
+ ?assertEqual({ok, Doc1}, fabric2_db:open_doc(Db, Doc#doc.id, [deleted])),
+ % Only works when the document has never existed to match CouchDB 3.x
+ % behavior
?assertThrow(conflict, fabric2_db:update_doc(Db, Doc)).