Example #1
0
        private void CreateDocs(uint n, bool verbose = false)
        {
            _R = new Random(42);
            using (var t = new TransactionHelper(_db)) {
                for (int i = 0; i < n; i++)
                {
                    var    docID = "doc-" + i.ToString();
                    double lat0  = RandomLatitude();
                    double lon0  = RandomLongitude();
                    double lat1  = Math.Min(lat0 + 0.5, 90.0);
                    double lon1  = Math.Min(lon0 + 0.5, 180.0);
                    var    body  = String.Format("({0}, {1}, {2}, {3})", lon0, lat0, lon1, lat1);

                    var rq = new C4DocPutRequest();
                    rq.docID = docID;
                    rq.body  = body;
                    rq.save  = true;
                    C4Error error;
                    var     doc = Native.c4doc_put(_db, rq, null, &error);
                    Assert.IsTrue(doc != null);
                    if (verbose)
                    {
                        Console.WriteLine("Added {0} -> {1}", docID, body);
                    }
                }
            }
        }
Example #2
0
 protected void CreateRev(string docID, string revID, string body, bool isNew = true)
 {
     using (var t = new TransactionHelper(_db)) {
         C4Error error;
         var     doc = Native.c4doc_get(_db, docID, false, &error);
         Assert.IsTrue(doc != null);
         var deleted = body == null;
         Assert.AreEqual(isNew ? 1 : 0, Native.c4doc_insertRevision(doc, revID, body, deleted, false, false, &error));
         Assert.IsTrue(Native.c4doc_save(doc, 20, &error));
         Native.c4doc_free(doc);
     }
 }
Example #3
0
        public void TestCreateVersionedDoc()
        {
            // Try reading doc with mustExist=true, which should fail:
            C4Error error;
            var     doc = Native.c4doc_get(_db, DOC_ID, true, &error);

            Assert.IsTrue(doc == null);
            Assert.AreEqual(C4ErrorDomain.ForestDB, error.domain);
            Assert.AreEqual(ForestDBStatus.KeyNotFound, (ForestDBStatus)error.code);

            // Now get the doc with mustExist=false, which returns an empty doc:
            doc = Native.c4doc_get(_db, DOC_ID, false, &error);
            Assert.IsTrue(doc != null);
            Assert.AreEqual((C4DocumentFlags)0, doc->flags);
            Assert.IsTrue(doc->docID.Equals(DOC_ID));
            Assert.IsTrue(doc->revID.buf == null);
            Assert.IsTrue(doc->selectedRev.revID.buf == null);

            using (var t = new TransactionHelper(_db)) {
                Assert.AreEqual(1, Native.c4doc_insertRevision(doc, REV_ID, BODY, false, false, false, &error));
                Assert.IsTrue(doc->revID.Equals(REV_ID));
                Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
                Assert.AreEqual(C4RevisionFlags.RevNew | C4RevisionFlags.RevLeaf, doc->selectedRev.flags);
                Assert.IsTrue(doc->selectedRev.body.Equals(BODY));
                Assert.IsTrue(Native.c4doc_save(doc, 20, &error));
                Native.c4doc_free(doc);
            }

            // Reload the doc:
            doc = Native.c4doc_get(_db, DOC_ID, true, &error);
            Assert.IsTrue(doc != null);
            Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
            Assert.IsTrue(doc->docID.Equals(DOC_ID));
            Assert.IsTrue(doc->revID.Equals(REV_ID));
            Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
            Assert.AreEqual(1UL, doc->selectedRev.sequence);
            Assert.IsTrue(doc->selectedRev.body.Equals(BODY));

            // Get the doc by its sequence:
            doc = Native.c4doc_getBySequence(_db, 1, &error);
            Assert.IsTrue(doc != null);
            Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
            Assert.IsTrue(doc->docID.Equals(DOC_ID));
            Assert.IsTrue(doc->revID.Equals(REV_ID));
            Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
            Assert.AreEqual(1UL, doc->selectedRev.sequence);
            Assert.IsTrue(doc->selectedRev.body.Equals(BODY));
        }
Example #4
0
        public void TestCreateMultipleRevisions()
        {
            const string BODY_2 = "{\"ok\":\"go\"}";

            CreateRev(DOC_ID, REV_ID, BODY);
            CreateRev(DOC_ID, REV_2_ID, BODY_2);
            CreateRev(DOC_ID, REV_2_ID, BODY_2, false); // test redundant insert

            // Reload the doc:
            C4Error error;
            var     doc = Native.c4doc_get(_db, DOC_ID, true, &error);

            Assert.IsTrue(doc != null);
            Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
            Assert.IsTrue(doc->docID.Equals(DOC_ID));
            Assert.IsTrue(doc->revID.Equals(REV_2_ID));
            Assert.IsTrue(doc->selectedRev.revID.Equals(REV_2_ID));
            Assert.AreEqual(2UL, doc->selectedRev.sequence);
            Assert.IsTrue(doc->selectedRev.body.Equals(BODY_2));

            // Select 1st revision:
            Assert.IsTrue(Native.c4doc_selectParentRevision(doc));
            Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
            Assert.AreEqual(1UL, doc->selectedRev.sequence);
            Assert.AreEqual(C4Slice.NULL, doc->selectedRev.body);
            Assert.IsTrue(Native.c4doc_hasRevisionBody(doc));
            Assert.IsTrue(Native.c4doc_loadRevisionBody(doc, &error)); // have to explicitly load the body
            Assert.IsTrue(doc->selectedRev.body.Equals(BODY));
            Assert.IsFalse(Native.c4doc_selectParentRevision(doc));

            // Compact database:
            Assert.IsTrue(Native.c4db_compact(_db, &error));

            doc = Native.c4doc_get(_db, DOC_ID, true, &error);
            Assert.IsTrue(doc != null);
            Assert.IsTrue(Native.c4doc_selectParentRevision(doc));
            Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
            Assert.AreEqual(1L, doc->selectedRev.sequence);
            Assert.IsTrue(doc->selectedRev.body.Equals(C4Slice.NULL));
            Assert.IsFalse(Native.c4doc_hasRevisionBody(doc));
            Assert.IsFalse(Native.c4doc_loadRevisionBody(doc, &error));

            using (var t = new TransactionHelper(_db)) {
                int nPurged = Native.c4doc_purgeRevision(doc, REV_2_ID, &error);
                Assert.AreEqual(2, nPurged);
                Assert.IsTrue(Native.c4doc_save(doc, 20, &error));
            }
        }
Example #5
0
        public void TestPut()
        {
            C4Error error;

            using (var t = new TransactionHelper(_db)) {
                C4DocPutRequest rq = new C4DocPutRequest();
                rq.docID = DOC_ID;
                rq.body  = BODY;
                rq.save  = true;
                var doc = Native.c4doc_put(_db, rq, null, &error);
                Assert.IsTrue(doc != null);
                Assert.IsTrue(doc->docID.Equals(DOC_ID));
                const string expectedRevID = "1-c10c25442d9fe14fa3ca0db4322d7f1e43140fab";
                Assert.IsTrue(doc->revID.Equals(expectedRevID));
                Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
                Assert.IsTrue(doc->selectedRev.revID.Equals(expectedRevID));
                Native.c4doc_free(doc);

                // Update doc:
                rq.body    = "{\"ok\":\"go\"}";
                rq.history = new[] { expectedRevID };
                ulong commonAncestorIndex;
                doc = Native.c4doc_put(_db, rq, &commonAncestorIndex, &error);
                Assert.IsTrue(doc != null);
                Assert.AreEqual(1UL, commonAncestorIndex);
                const string expectedRev2ID = "2-32c711b29ea3297e27f3c28c8b066a68e1bb3f7b";
                Assert.IsTrue(doc->revID.Equals(expectedRev2ID));
                Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
                Assert.IsTrue(doc->selectedRev.revID.Equals(expectedRev2ID));
                Native.c4doc_free(doc);

                // Insert existing rev:
                rq.body             = "{\"from\":\"elsewhere\"}";
                rq.existingRevision = true;
                rq.history          = new[] { REV_2_ID, expectedRevID };
                doc = Native.c4doc_put(_db, rq, &commonAncestorIndex, &error);
                Assert.IsTrue(doc != null);
                Assert.AreEqual(1UL, commonAncestorIndex);
                Assert.IsTrue(doc->revID.Equals(REV_2_ID));
                Assert.AreEqual(C4DocumentFlags.Exists | C4DocumentFlags.Conflicted, doc->flags);
                Assert.IsTrue(doc->selectedRev.revID.Equals(REV_2_ID));
                Native.c4doc_free(doc);
            }
        }
Example #6
0
        public void TestInsertRevisionWithHistory()
        {
            const string BODY_2 = @"{""ok"":""go""}";

            CreateRev(DOC_ID, REV_ID, BODY);
            CreateRev(DOC_ID, REV_2_ID, BODY_2);

            // Reload the doc:
            C4Error error;
            var     doc = Native.c4doc_get(_db, DOC_ID, true, &error);

            // Add 18 revisions; the last two entries in the history repeat the two existing revs:
            const int historyCount = 20;
            var       revIDs       = new List <string>(historyCount);
            var       rand         = new Random();

            for (uint i = historyCount - 1; i >= 2; i--)
            {
                revIDs.Add(String.Format("{0}-{1:x8}", i + 1, rand.Next()));
            }

            revIDs.Add(REV_2_ID);
            revIDs.Add(REV_ID);

            int n;

            using (var t = new TransactionHelper(_db)) {
                n = Native.c4doc_insertRevisionWithHistory(doc, @"{""foo"":true}", false, false, revIDs.ToArray(), &error);
            }

            if (n < 0)
            {
                Console.Error.WriteLine(String.Format("Error({0})", error));
            }

            Assert.AreEqual(historyCount - 2, n);
        }
Example #7
0
 public void TestCreateVersionedDoc()
 {
     // Try reading doc with mustExist=true, which should fail:
     C4Error error;
     var doc = Native.c4doc_get(_db, DOC_ID, true, &error);
     Assert.IsTrue(doc == null);
     Assert.AreEqual(C4ErrorDomain.ForestDB, error.domain);
     Assert.AreEqual(ForestDBStatus.KeyNotFound, (ForestDBStatus)error.code);
     
     // Now get the doc with mustExist=false, which returns an empty doc:
     doc = Native.c4doc_get(_db, DOC_ID, false, &error);
     Assert.IsTrue(doc != null);
     Assert.AreEqual((C4DocumentFlags)0, doc->flags);
     Assert.IsTrue(doc->docID.Equals(DOC_ID));
     Assert.IsTrue(doc->revID.buf == null);
     Assert.IsTrue(doc->selectedRev.revID.buf == null);
     
     using(var t = new TransactionHelper(_db)) {
         Assert.AreEqual(1, Native.c4doc_insertRevision(doc, REV_ID, BODY, false, false, false, &error));
         Assert.IsTrue(doc->revID.Equals(REV_ID));
         Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
         Assert.AreEqual(C4RevisionFlags.RevNew | C4RevisionFlags.RevLeaf, doc->selectedRev.flags);
         Assert.IsTrue(doc->selectedRev.body.Equals(BODY));
         Assert.IsTrue(Native.c4doc_save(doc, 20, &error));
         Native.c4doc_free(doc);
     }
     
     // Reload the doc:
     doc = Native.c4doc_get(_db, DOC_ID, true, &error);
     Assert.IsTrue(doc != null);
     Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
     Assert.IsTrue(doc->docID.Equals(DOC_ID));
     Assert.IsTrue(doc->revID.Equals(REV_ID));
     Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
     Assert.AreEqual(1UL, doc->selectedRev.sequence);
     Assert.IsTrue(doc->selectedRev.body.Equals(BODY));
     
     // Get the doc by its sequence:
     doc = Native.c4doc_getBySequence(_db, 1, &error);
     Assert.IsTrue(doc != null);
     Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
     Assert.IsTrue(doc->docID.Equals(DOC_ID));
     Assert.IsTrue(doc->revID.Equals(REV_ID));
     Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
     Assert.AreEqual(1UL, doc->selectedRev.sequence);
     Assert.IsTrue(doc->selectedRev.body.Equals(BODY));
 }
Example #8
0
 public void TestInsertRevisionWithHistory()
 {
     const string BODY_2 = @"{""ok"":""go""}";
     CreateRev(DOC_ID, REV_ID, BODY);
     CreateRev(DOC_ID, REV_2_ID, BODY_2);
     
     // Reload the doc:
     C4Error error;
     var doc = Native.c4doc_get(_db, DOC_ID, true, &error);
     
     // Add 18 revisions; the last two entries in the history repeat the two existing revs:
     const int historyCount = 20;
     var revIDs = new List<string>(historyCount);
     var rand = new Random();
     for(uint i = historyCount - 1; i >= 2; i--) {
         revIDs.Add(String.Format("{0}-{1:x8}", i+1, rand.Next())); 
     }
     
     revIDs.Add(REV_2_ID);
     revIDs.Add(REV_ID);
     
     int n;
     using(var t = new TransactionHelper(_db)) {
         n = Native.c4doc_insertRevisionWithHistory(doc, @"{""foo"":true}", false, false, revIDs.ToArray(), &error);
     }
     
     if(n < 0) {
         Console.Error.WriteLine(String.Format("Error({0})", error));
     }
     
     Assert.AreEqual(historyCount - 2, n);
 }
Example #9
0
 public void TestCreateMultipleRevisions()
 {
     const string BODY_2 = "{\"ok\":\"go\"}";
     CreateRev(DOC_ID, REV_ID, BODY);
     CreateRev(DOC_ID, REV_2_ID, BODY_2);
     CreateRev(DOC_ID, REV_2_ID, BODY_2, false); // test redundant insert
     
     // Reload the doc:
     C4Error error;
     var doc = Native.c4doc_get(_db, DOC_ID, true, &error);
     Assert.IsTrue(doc != null);
     Assert.AreEqual(C4DocumentFlags.Exists, doc->flags);
     Assert.IsTrue(doc->docID.Equals(DOC_ID));
     Assert.IsTrue(doc->revID.Equals(REV_2_ID));
     Assert.IsTrue(doc->selectedRev.revID.Equals(REV_2_ID));
     Assert.AreEqual(2UL, doc->selectedRev.sequence);
     Assert.IsTrue(doc->selectedRev.body.Equals(BODY_2));
     
     // Select 1st revision:
     Assert.IsTrue(Native.c4doc_selectParentRevision(doc));
     Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
     Assert.AreEqual(1UL, doc->selectedRev.sequence);
     Assert.AreEqual(C4Slice.NULL, doc->selectedRev.body);
     Assert.IsTrue(Native.c4doc_hasRevisionBody(doc));
     Assert.IsTrue(Native.c4doc_loadRevisionBody(doc, &error)); // have to explicitly load the body
     Assert.IsTrue(doc->selectedRev.body.Equals(BODY));
     Assert.IsFalse(Native.c4doc_selectParentRevision(doc));
     
     // Compact database:
     Assert.IsTrue(Native.c4db_compact(_db, &error));
     
     doc = Native.c4doc_get(_db, DOC_ID, true, &error);
     Assert.IsTrue(doc != null);
     Assert.IsTrue(Native.c4doc_selectParentRevision(doc));
     Assert.IsTrue(doc->selectedRev.revID.Equals(REV_ID));
     Assert.AreEqual(1L, doc->selectedRev.sequence);
     Assert.IsTrue(doc->selectedRev.body.Equals(C4Slice.NULL));
     Assert.IsFalse(Native.c4doc_hasRevisionBody(doc));
     Assert.IsFalse(Native.c4doc_loadRevisionBody(doc, &error));
     
     using(var t = new TransactionHelper(_db)) {
         int nPurged = Native.c4doc_purgeRevision(doc, REV_2_ID, &error);
         Assert.AreEqual(2, nPurged);
         Assert.IsTrue(Native.c4doc_save(doc, 20, &error));   
     }
 }
Example #10
0
 protected void CreateRev(string docID, string revID, string body, bool isNew = true)
 {
     using(var t = new TransactionHelper(_db)) {
         C4Error error;
         var doc = Native.c4doc_get(_db, docID, false, &error);
         Assert.IsTrue(doc != null);
         var deleted = body == null;
         Assert.AreEqual(isNew ? 1 : 0, Native.c4doc_insertRevision(doc, revID, body, deleted, false, false, &error));
         Assert.IsTrue(Native.c4doc_save(doc, 20, &error));
         Native.c4doc_free(doc);
     }
 }