diff options
author | Nick Vatamaniuc <vatamane@apache.org> | 2020-09-01 15:28:25 -0400 |
---|---|---|
committer | Nick Vatamaniuc <vatamane@apache.org> | 2020-09-01 16:29:49 -0400 |
commit | 5d2af3563b1c3784d289b2f91f202a0bf5ce750d (patch) | |
tree | c0ac6f2ce6cb26e9c6ddb0316d6c76518278c9df | |
parent | bf61a0051f6a0ae88cc40b7e6cd7710033fef33f (diff) | |
download | couchdb-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.erl | 11 | ||||
-rw-r--r-- | 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 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)). |