Skip to content

Commit

Permalink
Fix process attachments when the parent rev is a _deleted rev
Browse files Browse the repository at this point in the history
When the intermediate parent rev is _deleted rev, the status returned when getting the parentAttachments will be kCBLStatusOK instead of kCBLStatusNotFound. So it should go to the same logic as when the stastus is kCBLStatusNotFound to get the attachment from the attachment revpos instead.

#843
  • Loading branch information
pasin committed Aug 5, 2015
1 parent ff0c7c5 commit aefde4a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 5 deletions.
9 changes: 5 additions & 4 deletions Source/CBLDatabase+Attachments.m
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ - (BOOL) processAttachmentsForRevision: (CBL_MutableRevision*)rev
parentAttachments = [self attachmentsForDocID: rev.docID revID: prevRevID
status: &status];
if (!parentAttachments) {
if (status == kCBLStatusNotFound) {
if (status == kCBLStatusOK || status == kCBLStatusNotFound) {
if ([_attachments hasBlobForKey: attachment.blobKey]) {
// Parent revision's body isn't known (we are probably pulling a rev along
// with its entire history) but it's OK, we have the attachment already
Expand All @@ -352,11 +352,12 @@ - (BOOL) processAttachmentsForRevision: (CBL_MutableRevision*)rev
revpos: attachment->revpos
docID: rev.docID
ancestry: ancestry];
if (ancestorAttachment)
if (ancestorAttachment) {
*outStatus = kCBLStatusOK;
return ancestorAttachment;
} else
status = kCBLStatusBadAttachment;
}
if (status == kCBLStatusOK || status == kCBLStatusNotFound)
status = kCBLStatusBadAttachment;
*outStatus = status;
return nil;
}
Expand Down
46 changes: 45 additions & 1 deletion Unit-Tests/DatabaseAttachment_Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,51 @@ - (void) test15_MissingIntermediateRevs {
}


- (void) test16_FollowWithRevpos {
- (void) test16_IntermediateDeletedRevs {
// Put a revision that includes an _attachments dict:
NSData* attach1 = [@"This is the body of attach1" dataUsingEncoding: NSUTF8StringEncoding];
NSString* base64 = [CBLBase64 encode: attach1];
NSDictionary* attachmentDict = $dict({@"attach", $dict({@"content_type", @"text/plain"},
{@"data", base64})});
NSDictionary* props = $dict({@"_id", @"X"},
{@"_attachments", attachmentDict});
CBL_Revision* rev1;
CBLStatus status;
NSError* error;
rev1 = [db putRevision: [CBL_MutableRevision revisionWithProperties: props]
prevRevisionID: nil allowConflict: NO status: &status error: &error];
AssertEq(status, kCBLStatusCreated);
AssertNil(error);
AssertEqual(rev1[@"_attachments"][@"attach"][@"revpos"], @1);

// Insert a delete rev:
props = $dict({@"_id", rev1.docID},
{@"_deleted", $true});
CBL_Revision* rev2;
rev2 = [db putRevision: [CBL_MutableRevision revisionWithProperties: props] prevRevisionID:
rev1.revID allowConflict: NO status: &status error: &error] ;
AssertEq(status, kCBLStatusOK);
AssertNil(error);
Assert(rev2.deleted);

// Insert a revision several generations advanced but which hasn't changed the attachment:
CBL_MutableRevision* rev3 = [rev1 mutableCopy];
rev3[@"_rev"] = @"3-3333";
rev3[@"foo"] = @"bar";
[rev3 mutateAttachments: ^NSDictionary *(NSString *name, NSDictionary *att) {
NSMutableDictionary* nuAtt = [att mutableCopy];
[nuAtt removeObjectForKey: @"data"];
nuAtt[@"stub"] = @YES;
nuAtt[@"digest"] = @"md5-deadbeef"; // CouchDB adds MD5 digests!
return nuAtt;
}];
NSArray* history = @[rev2.revID, rev1.revID];
status = [db forceInsert: rev3 revisionHistory: history source: nil error: &error];
AssertEq(status, 200);
}


- (void) test17_FollowWithRevpos {
NSDictionary* attachInfo = $dict({@"content_type", @"text/plain"},
{@"digest", @"md5-DaUdFsLh8FKLbcBIDlU57g=="},
{@"follows", @YES},
Expand Down

0 comments on commit aefde4a

Please sign in to comment.