Ejemplo n.º 1
0
        public void TestAttachments()
        {
            const string testAttachmentName = "test_attachment";
            var          attachments        = database.Attachments;

            Assert.AreEqual(0, attachments.Count());
            Assert.AreEqual(0, attachments.AllKeys().Count());

            var attach1 = Encoding.UTF8.GetBytes("This is the body of attach1");
            var props   = new Dictionary <string, object> {
                { "foo", 1 },
                { "bar", false },
                { "_attachments", CreateAttachmentsDict(attach1, testAttachmentName, "text/plain", false) }
            };

            Status           status = new Status();
            RevisionInternal rev1   = database.PutRevision(new RevisionInternal(props), null, false, status);

            Assert.AreEqual(StatusCode.Created, status.GetCode());

            var att = database.GetAttachmentForRevision(rev1, testAttachmentName, status);

            Assert.IsNotNull(att, "Couldn't get attachment:  Status {0}", status.GetCode());
            Assert.AreEqual(attach1, att.Content);
            Assert.AreEqual("text/plain", att.ContentType);
            Assert.AreEqual(AttachmentEncoding.None, att.Encoding);

            var itemDict = new Dictionary <string, object> {
                { "content_type", "text/plain" },
                { "digest", "sha1-gOHUOBmIMoDCrMuGyaLWzf1hQTE=" },
                { "length", 27 },
                { "stub", true },
                { "revpos", 1 }
            };
            var attachmentDict = new Dictionary <string, object> {
                { testAttachmentName, itemDict }
            };
            var gotRev1 = database.GetDocumentWithIDAndRev(rev1.GetDocId(), rev1.GetRevId(), DocumentContentOptions.None);

            AssertDictionariesAreEqual(attachmentDict, gotRev1.GetAttachments());

            itemDict.Remove("stub");
            itemDict["data"] = Convert.ToBase64String(attach1);
            gotRev1          = database.GetDocumentWithIDAndRev(rev1.GetDocId(), rev1.GetRevId(), DocumentContentOptions.IncludeAttachments);
            var expandedRev = gotRev1.CopyWithDocID(rev1.GetDocId(), rev1.GetRevId());

            Assert.IsTrue(database.ExpandAttachments(expandedRev, 0, false, true, status));
            AssertDictionariesAreEqual(attachmentDict, expandedRev.GetAttachments());

            // Add a second revision that doesn't update the attachment:
            props = new Dictionary <string, object> {
                { "_id", rev1.GetDocId() },
                { "foo", 2 },
                { "bazz", false },
                { "_attachments", CreateAttachmentsStub(testAttachmentName) }
            };
            var rev2 = database.PutRevision(new RevisionInternal(props), rev1.GetRevId(), status);

            Assert.AreEqual(StatusCode.Created, status.GetCode());

            // Add a third revision of the same document:
            var attach2 = Encoding.UTF8.GetBytes("<html>And this is attach2</html>");

            props = new Dictionary <string, object> {
                { "_id", rev2.GetDocId() },
                { "foo", 2 },
                { "bazz", false },
                { "_attachments", CreateAttachmentsDict(attach2, testAttachmentName, "text/html", false) }
            };
            var rev3 = database.PutRevision(new RevisionInternal(props), rev2.GetRevId(), status);

            Assert.AreEqual(StatusCode.Created, status.GetCode());

            // Check the second revision's attachment
            att = database.GetAttachmentForRevision(rev2, testAttachmentName, status);
            Assert.IsNotNull(att, "Couldn't get attachment:  Status {0}", status.GetCode());
            Assert.AreEqual(attach1, att.Content);
            Assert.AreEqual("text/plain", att.ContentType);
            Assert.AreEqual(AttachmentEncoding.None, att.Encoding);

            expandedRev = rev2.CopyWithDocID(rev2.GetDocId(), rev2.GetRevId());
            Assert.IsTrue(database.ExpandAttachments(expandedRev, 2, false, true, status));
            AssertDictionariesAreEqual(new Dictionary <string, object> {
                { testAttachmentName, new Dictionary <string, object> {
                      { "stub", true },
                      { "revpos", 1 }
                  } }
            }, expandedRev.GetAttachments());

            // Check the 3rd revision's attachment:
            att = database.GetAttachmentForRevision(rev3, testAttachmentName, status);
            Assert.IsNotNull(att, "Couldn't get attachment:  Status {0}", status.GetCode());
            Assert.AreEqual(attach2, att.Content);
            Assert.AreEqual("text/html", att.ContentType);
            Assert.AreEqual(AttachmentEncoding.None, att.Encoding);

            expandedRev = rev3.CopyWithDocID(rev3.GetDocId(), rev3.GetRevId());
            Assert.IsTrue(database.ExpandAttachments(expandedRev, 2, false, true, status));
            attachmentDict = new Dictionary <string, object> {
                { testAttachmentName, new Dictionary <string, object> {
                      { "content_type", "text/html" },
                      { "data", "PGh0bWw+QW5kIHRoaXMgaXMgYXR0YWNoMjwvaHRtbD4=" },
                      { "digest", "sha1-s14XRTXlwvzYfjo1t1u0rjB+ZUA=" },
                      { "length", 32 },
                      { "revpos", 3 }
                  } }
            };
            AssertDictionariesAreEqual(attachmentDict, expandedRev.GetAttachments());

            // Examine the attachment store:
            Assert.AreEqual(2, attachments.Count());
            Assert.AreEqual(new HashSet <BlobKey> {
                BlobStore.KeyForBlob(attach1), BlobStore.KeyForBlob(attach2)
            }, attachments.AllKeys());
            database.Compact();
            Assert.AreEqual(1, attachments.Count());
            Assert.AreEqual(new HashSet <BlobKey> {
                BlobStore.KeyForBlob(attach2)
            }, attachments.AllKeys());
        }
Ejemplo n.º 2
0
        /// <exception cref="System.Exception"></exception>
        public virtual void TestAttachments()
        {
            string    testAttachmentName = "test_attachment";
            BlobStore attachments        = database.GetAttachments();

            NUnit.Framework.Assert.AreEqual(0, attachments.Count());
            NUnit.Framework.Assert.AreEqual(new HashSet <object>(), attachments.AllKeys());
            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());
            byte[] attach1 = Sharpen.Runtime.GetBytesForString("This is the body of attach1");
            database.InsertAttachmentForSequenceWithNameAndType(new ByteArrayInputStream(attach1
                                                                                         ), rev1.GetSequence(), testAttachmentName, "text/plain", rev1.GetGeneration());
            NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode());
            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));
            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> attachmentDict = new Dictionary <string, object>();

            attachmentDict.Put(testAttachmentName, innerDict);
            IDictionary <string, object> attachmentDictForSequence = database.GetAttachmentsDictForSequenceWithContent
                                                                         (rev1.GetSequence(), EnumSet.NoneOf <Database.TDContentOptions>());

            NUnit.Framework.Assert.AreEqual(attachmentDict, attachmentDictForSequence);
            RevisionInternal gotRev1 = database.GetDocumentWithIDAndRev(rev1.GetDocId(), rev1
                                                                        .GetRevId(), EnumSet.NoneOf <Database.TDContentOptions>());
            IDictionary <string, object> gotAttachmentDict = (IDictionary <string, object>)gotRev1
                                                             .GetProperties().Get("_attachments");

            NUnit.Framework.Assert.AreEqual(attachmentDict, gotAttachmentDict);
            // Check the attachment dict, with attachments included:
            Sharpen.Collections.Remove(innerDict, "stub");
            innerDict.Put("data", Base64.EncodeBytes(attach1));
            attachmentDictForSequence = database.GetAttachmentsDictForSequenceWithContent(rev1
                                                                                          .GetSequence(), EnumSet.Of(Database.TDContentOptions.TDIncludeAttachments));
            NUnit.Framework.Assert.AreEqual(attachmentDict, attachmentDictForSequence);
            gotRev1 = database.GetDocumentWithIDAndRev(rev1.GetDocId(), rev1.GetRevId(), EnumSet
                                                       .Of(Database.TDContentOptions.TDIncludeAttachments));
            gotAttachmentDict = (IDictionary <string, object>)gotRev1.GetProperties().Get("_attachments"
                                                                                          );
            NUnit.Framework.Assert.AreEqual(attachmentDict, gotAttachmentDict);
            // Add a second revision that doesn't update the attachment:
            IDictionary <string, object> rev2Properties = new Dictionary <string, object>();

            rev2Properties.Put("_id", rev1.GetDocId());
            rev2Properties.Put("foo", 2);
            rev2Properties.Put("bazz", false);
            RevisionInternal rev2 = database.PutRevision(new RevisionInternal(rev2Properties,
                                                                              database), rev1.GetRevId(), false, status);

            NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode());
            database.CopyAttachmentNamedFromSequenceToSequence(testAttachmentName, rev1.GetSequence
                                                                   (), rev2.GetSequence());
            // Add a third revision of the same document:
            IDictionary <string, object> rev3Properties = new Dictionary <string, object>();

            rev3Properties.Put("_id", rev2.GetDocId());
            rev3Properties.Put("foo", 2);
            rev3Properties.Put("bazz", false);
            RevisionInternal rev3 = database.PutRevision(new RevisionInternal(rev3Properties,
                                                                              database), rev2.GetRevId(), false, status);

            NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode());
            byte[] attach2 = Sharpen.Runtime.GetBytesForString("<html>And this is attach2</html>"
                                                               );
            database.InsertAttachmentForSequenceWithNameAndType(new ByteArrayInputStream(attach2
                                                                                         ), rev3.GetSequence(), testAttachmentName, "text/html", rev2.GetGeneration());
            // Check the 2nd revision's attachment:
            Attachment attachment2 = database.GetAttachmentForSequence(rev2.GetSequence(), testAttachmentName
                                                                       );

            NUnit.Framework.Assert.AreEqual("text/plain", attachment2.GetContentType());
            data = IOUtils.ToByteArray(attachment2.GetContent());
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(attach1, data));
            // Check the 3rd revision's attachment:
            Attachment attachment3 = database.GetAttachmentForSequence(rev3.GetSequence(), testAttachmentName
                                                                       );

            NUnit.Framework.Assert.AreEqual("text/html", attachment3.GetContentType());
            data = IOUtils.ToByteArray(attachment3.GetContent());
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(attach2, data));
            // Examine the attachment store:
            NUnit.Framework.Assert.AreEqual(2, attachments.Count());
            ICollection <BlobKey> expected = new HashSet <BlobKey>();

            expected.AddItem(BlobStore.KeyForBlob(attach1));
            expected.AddItem(BlobStore.KeyForBlob(attach2));
            NUnit.Framework.Assert.AreEqual(expected, attachments.AllKeys());
            database.Compact();
            // This clears the body of the first revision
            NUnit.Framework.Assert.AreEqual(1, attachments.Count());
            ICollection <BlobKey> expected2 = new HashSet <BlobKey>();

            expected2.AddItem(BlobStore.KeyForBlob(attach2));
            NUnit.Framework.Assert.AreEqual(expected2, attachments.AllKeys());
        }
        public void TestAttachments()
        {
            var testAttachmentName = "test_attachment";
            var attachments        = database.Attachments;

            Assert.AreEqual(0, attachments.Count());
            Assert.AreEqual(0, attachments.AllKeys().Count());

            var rev1Properties = new Dictionary <string, object>();

            rev1Properties["foo"] = 1;
            rev1Properties["bar"] = false;

            var status = new Status();
            var rev1   = database.PutRevision(
                new RevisionInternal(rev1Properties), null, false, status);

            Assert.AreEqual(StatusCode.Created, status.GetCode());

            var attach1 = Encoding.UTF8.GetBytes("This is the body of attach1");

            database.InsertAttachmentForSequenceWithNameAndType(
                new ByteArrayInputStream(attach1),
                rev1.GetSequence(),
                testAttachmentName,
                "text/plain",
                rev1.GetGeneration());

            //We must set the no_attachments column for the rev to false, as we are using an internal
            //private API call above (database.insertAttachmentForSequenceWithNameAndType) which does
            //not set the no_attachments column on revs table
            try
            {
                var args = new ContentValues();
                args.Put("no_attachments", false);
                database.StorageEngine.Update(
                    "revs",
                    args,
                    "sequence=?",
                    new[] { rev1.GetSequence().ToString() }
                    );
            }
            catch (SQLException e)
            {
                Log.E(Tag, "Error setting rev1 no_attachments to false", e);
                throw new CouchbaseLiteException(StatusCode.InternalServerError);
            }

            var attachment = database.GetAttachmentForSequence(
                rev1.GetSequence(),
                testAttachmentName
                );

            Assert.AreEqual("text/plain", attachment.ContentType);
            var data = attachment.Content.ToArray();

            Assert.IsTrue(Arrays.Equals(attach1, data));

            attachment.Dispose();

            var innerDict = new Dictionary <string, object>();

            innerDict["content_type"] = "text/plain";
            innerDict["digest"]       = "sha1-gOHUOBmIMoDCrMuGyaLWzf1hQTE=";
            innerDict["length"]       = 27;
            innerDict["stub"]         = true;
            innerDict["revpos"]       = 1;

            var attachmentDict = new Dictionary <string, object>();

            attachmentDict[testAttachmentName] = innerDict;
            var attachmentDictForSequence = database.GetAttachmentsDictForSequenceWithContent(rev1.GetSequence(), DocumentContentOptions.None);

            Assert.AreEqual(new SortedDictionary <string, object>(attachmentDict), new SortedDictionary <string, object>(attachmentDictForSequence));//Assert.AreEqual(1, attachmentDictForSequence.Count);
            var gotRev1 = database.GetDocumentWithIDAndRev(rev1.GetDocId(),
                                                           rev1.GetRevId(), DocumentContentOptions.IncludeAttachments);
            var gotAttachmentDict = gotRev1.GetProperties()
                                    .Get("_attachments")
                                    .AsDictionary <string, object>();

            Assert.AreEqual(attachmentDict.Select(kvp => kvp.Key).OrderBy(k => k), gotAttachmentDict.Select(kvp => kvp.Key).OrderBy(k => k));

            // Check the attachment dict, with attachments included:
            innerDict.Remove("stub");
            innerDict.Put("data", Convert.ToBase64String(attach1));
            attachmentDictForSequence = database.GetAttachmentsDictForSequenceWithContent(
                rev1.GetSequence(), DocumentContentOptions.IncludeAttachments);
            Assert.AreEqual(new SortedDictionary <string, object>(attachmentDict[testAttachmentName].AsDictionary <string, object>()), new SortedDictionary <string, object>(attachmentDictForSequence[testAttachmentName].AsDictionary <string, object>()));

            gotRev1 = database.GetDocumentWithIDAndRev(
                rev1.GetDocId(), rev1.GetRevId(), DocumentContentOptions.IncludeAttachments);
            gotAttachmentDict = gotRev1.GetProperties()
                                .Get("_attachments")
                                .AsDictionary <string, object>()
                                .Get(testAttachmentName)
                                .AsDictionary <string, object>();
            Assert.AreEqual(innerDict.Select(kvp => kvp.Key).OrderBy(k => k), gotAttachmentDict.Select(kvp => kvp.Key).OrderBy(k => k));

            // Add a second revision that doesn't update the attachment:
            database.BeginTransaction();
            var rev2Properties = new Dictionary <string, object>();

            rev2Properties.Put("_id", rev1.GetDocId());
            rev2Properties["foo"]  = 2;
            rev2Properties["bazz"] = false;
            var rev2 = database.PutRevision(new RevisionInternal(rev2Properties), rev1.GetRevId(), false, status);

            Assert.AreEqual(StatusCode.Created, status.GetCode());

            database.CopyAttachmentNamedFromSequenceToSequence(
                testAttachmentName, rev1.GetSequence(), rev2.GetSequence());
            database.EndTransaction(true);
            // Add a third revision of the same document:
            var rev3Properties = new Dictionary <string, object>();

            rev3Properties.Put("_id", rev2.GetDocId());
            rev3Properties["foo"]  = 2;
            rev3Properties["bazz"] = false;
            database.BeginTransaction();
            var rev3 = database.PutRevision(new RevisionInternal(
                                                rev3Properties), rev2.GetRevId(), false, status);

            Assert.AreEqual(StatusCode.Created, status.GetCode());

            var attach2 = Encoding.UTF8.GetBytes("<html>And this is attach2</html>");

            database.InsertAttachmentForSequenceWithNameAndType(
                new ByteArrayInputStream(attach2), rev3.GetSequence(),
                testAttachmentName, "text/html", rev2.GetGeneration());
            database.EndTransaction(true);
            // Check the 2nd revision's attachment:
            var attachment2 = database.GetAttachmentForSequence(rev2.GetSequence(), testAttachmentName);

            Assert.AreEqual("text/plain", attachment2.ContentType);

            data = attachment2.Content.ToArray();
            Assert.IsTrue(Arrays.Equals(attach1, data));

            attachment2.Dispose();

            // Check the 3rd revision's attachment:
            var attachment3 = database.GetAttachmentForSequence(rev3.GetSequence(), testAttachmentName);

            Assert.AreEqual("text/html", attachment3.ContentType);

            data = attachment3.Content.ToArray();
            Assert.IsTrue(Arrays.Equals(attach2, data));

            var attachmentDictForRev3 = database.GetAttachmentsDictForSequenceWithContent(rev3.GetSequence(), DocumentContentOptions.None)
                                        .Get(testAttachmentName)
                                        .AsDictionary <string, object>();

            if (attachmentDictForRev3.ContainsKey("follows"))
            {
                if (((bool)attachmentDictForRev3.Get("follows")) == true)
                {
                    throw new RuntimeException("Did not expected attachment dict 'follows' key to be true"
                                               );
                }
                else
                {
                    throw new RuntimeException("Did not expected attachment dict to have 'follows' key"
                                               );
                }
            }

            attachment3.Dispose();

            // Examine the attachment store:
            Assert.AreEqual(2, attachments.Count());

            var expected = new HashSet <BlobKey>();

            expected.AddItem(BlobStore.KeyForBlob(attach1));
            expected.AddItem(BlobStore.KeyForBlob(attach2));
            Assert.AreEqual(expected.Count, attachments.AllKeys().Count());

            foreach (var key in attachments.AllKeys())
            {
                Assert.IsTrue(expected.Contains(key));
            }

            database.Compact();

            // This clears the body of the first revision
            Assert.AreEqual(1, attachments.Count());

            var expected2 = new HashSet <BlobKey>();

            expected2.AddItem(BlobStore.KeyForBlob(attach2));
            Assert.AreEqual(expected2.Count, attachments.AllKeys().Count());

            foreach (var key in attachments.AllKeys())
            {
                Assert.IsTrue(expected2.Contains(key));
            }
        }
Ejemplo n.º 4
0
        /// <exception cref="System.Exception"></exception>
        public virtual void TestAttachments()
        {
            string    testAttachmentName = "test_attachment";
            BlobStore attachments        = database.GetAttachments();

            NUnit.Framework.Assert.AreEqual(0, attachments.Count());
            NUnit.Framework.Assert.AreEqual(new HashSet <object>(), attachments.AllKeys());
            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());
            byte[] attach1 = Sharpen.Runtime.GetBytesForString("This is the body of attach1");
            database.InsertAttachmentForSequenceWithNameAndType(new ByteArrayInputStream(attach1
                                                                                         ), rev1.GetSequence(), testAttachmentName, "text/plain", rev1.GetGeneration());
            NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode());
            //We must set the no_attachments column for the rev to false, as we are using an internal
            //private API call above (database.insertAttachmentForSequenceWithNameAndType) which does
            //not set the no_attachments column on revs table
            try
            {
                ContentValues args = new ContentValues();
                args.Put("no_attachments=", false);
                database.GetDatabase().Update("revs", args, "sequence=?", new string[] { rev1.GetSequence
                                                                                             ().ToString() });
            }
            catch (SQLException e)
            {
                Log.E(Database.Tag, "Error setting rev1 no_attachments to false", e);
                throw new CouchbaseLiteException(Status.InternalServerError);
            }
            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));
            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> attachmentDict = new Dictionary <string, object>();

            attachmentDict.Put(testAttachmentName, innerDict);
            IDictionary <string, object> attachmentDictForSequence = database.GetAttachmentsDictForSequenceWithContent
                                                                         (rev1.GetSequence(), EnumSet.NoneOf <Database.TDContentOptions>());

            NUnit.Framework.Assert.AreEqual(attachmentDict, attachmentDictForSequence);
            RevisionInternal gotRev1 = database.GetDocumentWithIDAndRev(rev1.GetDocId(), rev1
                                                                        .GetRevId(), EnumSet.NoneOf <Database.TDContentOptions>());
            IDictionary <string, object> gotAttachmentDict = (IDictionary <string, object>)gotRev1
                                                             .GetProperties().Get("_attachments");

            NUnit.Framework.Assert.AreEqual(attachmentDict, gotAttachmentDict);
            // Check the attachment dict, with attachments included:
            Sharpen.Collections.Remove(innerDict, "stub");
            innerDict.Put("data", Base64.EncodeBytes(attach1));
            attachmentDictForSequence = database.GetAttachmentsDictForSequenceWithContent(rev1
                                                                                          .GetSequence(), EnumSet.Of(Database.TDContentOptions.TDIncludeAttachments));
            NUnit.Framework.Assert.AreEqual(attachmentDict, attachmentDictForSequence);
            gotRev1 = database.GetDocumentWithIDAndRev(rev1.GetDocId(), rev1.GetRevId(), EnumSet
                                                       .Of(Database.TDContentOptions.TDIncludeAttachments));
            gotAttachmentDict = (IDictionary <string, object>)gotRev1.GetProperties().Get("_attachments"
                                                                                          );
            NUnit.Framework.Assert.AreEqual(attachmentDict, gotAttachmentDict);
            // Add a second revision that doesn't update the attachment:
            IDictionary <string, object> rev2Properties = new Dictionary <string, object>();

            rev2Properties.Put("_id", rev1.GetDocId());
            rev2Properties.Put("foo", 2);
            rev2Properties.Put("bazz", false);
            RevisionInternal rev2 = database.PutRevision(new RevisionInternal(rev2Properties,
                                                                              database), rev1.GetRevId(), false, status);

            NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode());
            database.CopyAttachmentNamedFromSequenceToSequence(testAttachmentName, rev1.GetSequence
                                                                   (), rev2.GetSequence());
            // Add a third revision of the same document:
            IDictionary <string, object> rev3Properties = new Dictionary <string, object>();

            rev3Properties.Put("_id", rev2.GetDocId());
            rev3Properties.Put("foo", 2);
            rev3Properties.Put("bazz", false);
            RevisionInternal rev3 = database.PutRevision(new RevisionInternal(rev3Properties,
                                                                              database), rev2.GetRevId(), false, status);

            NUnit.Framework.Assert.AreEqual(Status.Created, status.GetCode());
            byte[] attach2 = Sharpen.Runtime.GetBytesForString("<html>And this is attach2</html>"
                                                               );
            database.InsertAttachmentForSequenceWithNameAndType(new ByteArrayInputStream(attach2
                                                                                         ), rev3.GetSequence(), testAttachmentName, "text/html", rev2.GetGeneration());
            // Check the 2nd revision's attachment:
            Attachment attachment2 = database.GetAttachmentForSequence(rev2.GetSequence(), testAttachmentName
                                                                       );

            NUnit.Framework.Assert.AreEqual("text/plain", attachment2.GetContentType());
            data = IOUtils.ToByteArray(attachment2.GetContent());
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(attach1, data));
            // Check the 3rd revision's attachment:
            Attachment attachment3 = database.GetAttachmentForSequence(rev3.GetSequence(), testAttachmentName
                                                                       );

            NUnit.Framework.Assert.AreEqual("text/html", attachment3.GetContentType());
            data = IOUtils.ToByteArray(attachment3.GetContent());
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(attach2, data));
            IDictionary <string, object> attachmentDictForRev3 = (IDictionary <string, object>)
                                                                 database.GetAttachmentsDictForSequenceWithContent(rev3.GetSequence(), EnumSet.NoneOf
                                                                                                                   <Database.TDContentOptions>()).Get(testAttachmentName);

            if (attachmentDictForRev3.ContainsKey("follows"))
            {
                if (((bool)attachmentDictForRev3.Get("follows")) == true)
                {
                    throw new RuntimeException("Did not expected attachment dict 'follows' key to be true"
                                               );
                }
                else
                {
                    throw new RuntimeException("Did not expected attachment dict to have 'follows' key"
                                               );
                }
            }
            // Examine the attachment store:
            NUnit.Framework.Assert.AreEqual(2, attachments.Count());
            ICollection <BlobKey> expected = new HashSet <BlobKey>();

            expected.AddItem(BlobStore.KeyForBlob(attach1));
            expected.AddItem(BlobStore.KeyForBlob(attach2));
            NUnit.Framework.Assert.AreEqual(expected, attachments.AllKeys());
            database.Compact();
            // This clears the body of the first revision
            NUnit.Framework.Assert.AreEqual(1, attachments.Count());
            ICollection <BlobKey> expected2 = new HashSet <BlobKey>();

            expected2.AddItem(BlobStore.KeyForBlob(attach2));
            NUnit.Framework.Assert.AreEqual(expected2, attachments.AllKeys());
        }