You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2020/09/03 17:36:58 UTC

[couchdb] branch prototype/fdb-layer updated: Allow creating new deleted documents

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/prototype/fdb-layer by this push:
     new 947308d  Allow creating new deleted documents
947308d is described below

commit 947308d61d8016d9624d53a1a4dc91b7d92a0464
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Tue Sep 1 15:28:25 2020 -0400

    Allow 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"
    }
    ```
---
 src/fabric/src/fabric2_db.erl              | 11 +++++++----
 src/fabric/test/fabric2_doc_crud_tests.erl | 12 ++++++++++--
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/fabric/src/fabric2_db.erl b/src/fabric/src/fabric2_db.erl
index 4ac1055..b62f26e 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 ce3757d..7a24b7d 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)).