/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception> public virtual void TestPutAttachment() { string testAttachmentName = "test_attachment"; BlobStore attachments = database.GetAttachments(); attachments.DeleteBlobs(); NUnit.Framework.Assert.AreEqual(0, attachments.Count()); // Put a revision that includes an _attachments dict: byte[] attach1 = Sharpen.Runtime.GetBytesForString("This is the body of attach1"); string base64 = Base64.EncodeBytes(attach1); IDictionary <string, object> attachment = new Dictionary <string, object>(); attachment.Put("content_type", "text/plain"); attachment.Put("data", base64); IDictionary <string, object> attachmentDict = new Dictionary <string, object>(); attachmentDict.Put(testAttachmentName, attachment); IDictionary <string, object> properties = new Dictionary <string, object>(); properties.Put("foo", 1); properties.Put("bar", false); properties.Put("_attachments", attachmentDict); RevisionInternal rev1 = database.PutRevision(new RevisionInternal(properties, database ), null, false); // Examine the attachment store: NUnit.Framework.Assert.AreEqual(1, attachments.Count()); // Get the revision: RevisionInternal gotRev1 = database.GetDocumentWithIDAndRev(rev1.GetDocId(), rev1 .GetRevId(), EnumSet.NoneOf <Database.TDContentOptions>()); IDictionary <string, object> gotAttachmentDict = (IDictionary <string, object>)gotRev1 .GetProperties().Get("_attachments"); IDictionary <string, object> innerDict = new Dictionary <string, object>(); innerDict.Put("content_type", "text/plain"); innerDict.Put("digest", "sha1-gOHUOBmIMoDCrMuGyaLWzf1hQTE="); innerDict.Put("length", 27); innerDict.Put("stub", true); innerDict.Put("revpos", 1); IDictionary <string, object> expectAttachmentDict = new Dictionary <string, object> (); expectAttachmentDict.Put(testAttachmentName, innerDict); NUnit.Framework.Assert.AreEqual(expectAttachmentDict, gotAttachmentDict); // Update the attachment directly: byte[] attachv2 = Sharpen.Runtime.GetBytesForString("Replaced body of attach"); bool gotExpectedErrorCode = false; try { database.UpdateAttachment(testAttachmentName, new ByteArrayInputStream(attachv2), "application/foo", rev1.GetDocId(), null); } catch (CouchbaseLiteException e) { gotExpectedErrorCode = (e.GetCBLStatus().GetCode() == Status.Conflict); } NUnit.Framework.Assert.IsTrue(gotExpectedErrorCode); gotExpectedErrorCode = false; try { database.UpdateAttachment(testAttachmentName, new ByteArrayInputStream(attachv2), "application/foo", rev1.GetDocId(), "1-bogus"); } catch (CouchbaseLiteException e) { gotExpectedErrorCode = (e.GetCBLStatus().GetCode() == Status.Conflict); } NUnit.Framework.Assert.IsTrue(gotExpectedErrorCode); gotExpectedErrorCode = false; RevisionInternal rev2 = null; try { rev2 = database.UpdateAttachment(testAttachmentName, new ByteArrayInputStream(attachv2 ), "application/foo", rev1.GetDocId(), rev1.GetRevId()); } catch (CouchbaseLiteException) { gotExpectedErrorCode = true; } NUnit.Framework.Assert.IsFalse(gotExpectedErrorCode); NUnit.Framework.Assert.AreEqual(rev1.GetDocId(), rev2.GetDocId()); NUnit.Framework.Assert.AreEqual(2, rev2.GetGeneration()); // Get the updated revision: RevisionInternal gotRev2 = database.GetDocumentWithIDAndRev(rev2.GetDocId(), rev2 .GetRevId(), EnumSet.NoneOf <Database.TDContentOptions>()); attachmentDict = (IDictionary <string, object>)gotRev2.GetProperties().Get("_attachments" ); innerDict = new Dictionary <string, object>(); innerDict.Put("content_type", "application/foo"); innerDict.Put("digest", "sha1-mbT3208HI3PZgbG4zYWbDW2HsPk="); innerDict.Put("length", 23); innerDict.Put("stub", true); innerDict.Put("revpos", 2); expectAttachmentDict.Put(testAttachmentName, innerDict); NUnit.Framework.Assert.AreEqual(expectAttachmentDict, attachmentDict); // Delete the attachment: gotExpectedErrorCode = false; try { database.UpdateAttachment("nosuchattach", null, null, rev2.GetDocId(), rev2.GetRevId ()); } catch (CouchbaseLiteException e) { gotExpectedErrorCode = (e.GetCBLStatus().GetCode() == Status.NotFound); } NUnit.Framework.Assert.IsTrue(gotExpectedErrorCode); gotExpectedErrorCode = false; try { database.UpdateAttachment("nosuchattach", null, null, "nosuchdoc", "nosuchrev"); } catch (CouchbaseLiteException e) { gotExpectedErrorCode = (e.GetCBLStatus().GetCode() == Status.NotFound); } NUnit.Framework.Assert.IsTrue(gotExpectedErrorCode); RevisionInternal rev3 = database.UpdateAttachment(testAttachmentName, null, null, rev2.GetDocId(), rev2.GetRevId()); NUnit.Framework.Assert.AreEqual(rev2.GetDocId(), rev3.GetDocId()); NUnit.Framework.Assert.AreEqual(3, rev3.GetGeneration()); // Get the updated revision: RevisionInternal gotRev3 = database.GetDocumentWithIDAndRev(rev3.GetDocId(), rev3 .GetRevId(), EnumSet.NoneOf <Database.TDContentOptions>()); attachmentDict = (IDictionary <string, object>)gotRev3.GetProperties().Get("_attachments" ); NUnit.Framework.Assert.IsNull(attachmentDict); database.Close(); }
/// <exception cref="System.Exception"></exception> public virtual void TestPutLargeAttachment() { string testAttachmentName = "test_attachment"; BlobStore attachments = database.GetAttachments(); attachments.DeleteBlobs(); NUnit.Framework.Assert.AreEqual(0, attachments.Count()); Status status = new Status(); IDictionary <string, object> rev1Properties = new Dictionary <string, object>(); rev1Properties.Put("foo", 1); rev1Properties.Put("bar", false); RevisionInternal rev1 = database.PutRevision(new RevisionInternal(rev1Properties, database), null, false, status); NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode()); StringBuilder largeAttachment = new StringBuilder(); for (int i = 0; i < Database.kBigAttachmentLength; i++) { largeAttachment.Append("big attachment!"); } byte[] attach1 = Sharpen.Runtime.GetBytesForString(largeAttachment.ToString()); database.InsertAttachmentForSequenceWithNameAndType(new ByteArrayInputStream(attach1 ), rev1.GetSequence(), testAttachmentName, "text/plain", rev1.GetGeneration()); Attachment attachment = database.GetAttachmentForSequence(rev1.GetSequence(), testAttachmentName ); NUnit.Framework.Assert.AreEqual("text/plain", attachment.GetContentType()); byte[] data = IOUtils.ToByteArray(attachment.GetContent()); NUnit.Framework.Assert.IsTrue(Arrays.Equals(attach1, data)); EnumSet <Database.TDContentOptions> contentOptions = EnumSet.Of(Database.TDContentOptions .TDIncludeAttachments, Database.TDContentOptions.TDBigAttachmentsFollow); IDictionary <string, object> attachmentDictForSequence = database.GetAttachmentsDictForSequenceWithContent (rev1.GetSequence(), contentOptions); IDictionary <string, object> innerDict = (IDictionary <string, object>)attachmentDictForSequence .Get(testAttachmentName); if (!innerDict.ContainsKey("stub")) { throw new RuntimeException("Expected attachment dict to have 'stub' key"); } if (((bool)innerDict.Get("stub")) == false) { throw new RuntimeException("Expected attachment dict 'stub' key to be true"); } if (!innerDict.ContainsKey("follows")) { throw new RuntimeException("Expected attachment dict to have 'follows' key"); } RevisionInternal rev1WithAttachments = database.GetDocumentWithIDAndRev(rev1.GetDocId (), rev1.GetRevId(), contentOptions); // Map<String,Object> rev1PropertiesPrime = rev1WithAttachments.getProperties(); // rev1PropertiesPrime.put("foo", 2); IDictionary <string, object> rev1WithAttachmentsProperties = rev1WithAttachments.GetProperties (); IDictionary <string, object> rev2Properties = new Dictionary <string, object>(); rev2Properties.Put("_id", rev1WithAttachmentsProperties.Get("_id")); rev2Properties.Put("foo", 2); RevisionInternal newRev = new RevisionInternal(rev2Properties, database); RevisionInternal rev2 = database.PutRevision(newRev, rev1WithAttachments.GetRevId (), false, status); NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode()); database.CopyAttachmentNamedFromSequenceToSequence(testAttachmentName, rev1WithAttachments .GetSequence(), rev2.GetSequence()); // Check the 2nd revision's attachment: Attachment rev2FetchedAttachment = database.GetAttachmentForSequence(rev2.GetSequence (), testAttachmentName); NUnit.Framework.Assert.AreEqual(attachment.GetLength(), rev2FetchedAttachment.GetLength ()); NUnit.Framework.Assert.AreEqual(attachment.GetMetadata(), rev2FetchedAttachment.GetMetadata ()); NUnit.Framework.Assert.AreEqual(attachment.GetContentType(), rev2FetchedAttachment .GetContentType()); // Add a third revision of the same document: IDictionary <string, object> rev3Properties = new Dictionary <string, object>(); rev3Properties.Put("_id", rev2.GetProperties().Get("_id")); rev3Properties.Put("foo", 3); rev3Properties.Put("baz", false); RevisionInternal rev3 = new RevisionInternal(rev3Properties, database); rev3 = database.PutRevision(rev3, rev2.GetRevId(), false, status); NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode()); byte[] attach3 = Sharpen.Runtime.GetBytesForString("<html><blink>attach3</blink></html>" ); database.InsertAttachmentForSequenceWithNameAndType(new ByteArrayInputStream(attach3 ), rev3.GetSequence(), testAttachmentName, "text/html", rev3.GetGeneration()); // Check the 3rd revision's attachment: Attachment rev3FetchedAttachment = database.GetAttachmentForSequence(rev3.GetSequence (), testAttachmentName); data = IOUtils.ToByteArray(rev3FetchedAttachment.GetContent()); NUnit.Framework.Assert.IsTrue(Arrays.Equals(attach3, data)); NUnit.Framework.Assert.AreEqual("text/html", rev3FetchedAttachment.GetContentType ()); // TODO: why doesn't this work? // Assert.assertEquals(attach3.length, rev3FetchedAttachment.getLength()); ICollection <BlobKey> blobKeys = database.GetAttachments().AllKeys(); NUnit.Framework.Assert.AreEqual(2, blobKeys.Count); database.Compact(); blobKeys = database.GetAttachments().AllKeys(); NUnit.Framework.Assert.AreEqual(1, blobKeys.Count); }