private static void DoOpen(C4Socket *socket, C4Address *address, C4Slice options)
        {
            var builder = new UriBuilder {
                Host   = address->hostname.CreateString(),
                Scheme = address->scheme.CreateString(),
                Port   = address->port,
                Path   = address->path.CreateString()
            };

            Uri uri;

            try {
                uri = builder.Uri;
            } catch (Exception) {
                Native.c4socket_closed(socket, new C4Error(C4ErrorCode.InvalidParameter));
                return;
            }

            if (uri == null)
            {
                Native.c4socket_closed(socket, new C4Error(C4ErrorCode.InvalidParameter));
                return;
            }

            var opts =
                FLSliceExtensions.ToObject(NativeRaw.FLValue_FromTrustedData((FLSlice)options)) as
                Dictionary <string, object>;
            var replicationOptions = new ReplicatorOptionsDictionary(opts);
            var socketWrapper      = new WebSocketWrapper(uri, socket, replicationOptions);
            var id = Interlocked.Increment(ref _NextID);

            socket->nativeHandle = (void *)id;
            Sockets[id]          = socketWrapper;
            socketWrapper.Start();
        }
Beispiel #2
0
        protected void CreateRev(string docID, C4Slice revID, C4Slice body, bool isNew = true)
        {
            LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
            try {
                var curDoc = (C4Document *)LiteCoreBridge.Check(err => Native.c4doc_get(Db, docID,
                                                                                        false, err));
                var history = new[] { revID, curDoc->revID };
                fixed(C4Slice *h = history)
                {
                    var rq = new C4DocPutRequest {
                        existingRevision = true,
                        docID            = curDoc->docID,
                        history          = h,
                        historyCount     = curDoc->revID.buf != null ? 2UL : 1UL,
                        body             = body,
                        deletion         = body.buf == null,
                        save             = true
                    };

                    var doc = (C4Document *)LiteCoreBridge.Check(err => {
                        var localRq = rq;
                        return(Native.c4doc_put(Db, &localRq, null, err));
                    });

                    Native.c4doc_free(doc);
                    Native.c4doc_free(curDoc);
                }
            } finally {
                LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err));
            }
        }
        public void TestQueryIndex()
        {
            RunTestVariants(() => {
                CreateIndex();

                var e = (C4QueryEnumerator *)LiteCoreBridge.Check(err => Native.c4view_query(_view, null, err));

                ulong i = 0;
                C4Error error;
                string buf;
                while (Native.c4queryenum_next(e, &error))
                {
                    ++i;
                    if (i <= 100)
                    {
                        buf = i.ToString();
                        e->docSequence.Should().Be(i, "because the sequences should be ordered");
                    }
                    else
                    {
                        buf = $"\"doc-{i-100:D3}\"";
                        e->docSequence.Should().Be(i - 100, "because the sequence number should be ordered");
                    }

                    Native.c4key_toJSON(&e->key).Should().Be(buf, "because the key on the enumerator should be correct");
                    e->value.Equals(C4Slice.Constant("1234")).Should().BeTrue("because the value should be correct");
                }

                Native.c4queryenum_free(e);
                error.Code.Should().Be(0, "because otherwise an error occurred somewhere");
                i.Should().Be(200, "because all index entries should be covered");
            });
        }
        private void UpdateIndex()
        {
            var ind = (C4Indexer *)LiteCoreBridge.Check(err => Native.c4indexer_begin(Db,
                                                                                      new[] { _view }, err));
            var         e = (C4DocEnumerator *)LiteCoreBridge.Check(err => Native.c4indexer_enumerateDocuments(ind, err));
            C4Document *doc;
            C4Error     error;

            while (null != (doc = Native.c4enum_nextDocument(e, &error)))
            {
                // Index 'doc':
                var keys   = new C4Key *[2];
                var values = new C4Slice[2];
                keys[0] = Native.c4key_new();
                keys[1] = Native.c4key_new();
                NativeRaw.c4key_addString(keys[0], doc->docID);
                Native.c4key_addNumber(keys[1], doc->sequence);
                values[0] = values[1] = C4Slice.Constant("1234");
                LiteCoreBridge.Check(err => Native.c4indexer_emit(ind, doc, 0, keys, values, err));
                Native.c4key_free(keys[0]);
                Native.c4key_free(keys[1]);
                Native.c4doc_free(doc);
            }

            error.Code.Should().Be(0, "because otherwise an error occurred somewhere");
            Native.c4enum_free(e);
            LiteCoreBridge.Check(err => Native.c4indexer_end(ind, true, err));
        }
Beispiel #5
0
        public void TestDBObserver()
        {
            RunTestVariants(() =>
            {
                var handle = GCHandle.Alloc(this);
                try {
                    _dbObserver = Native.c4dbobs_create(Db, DBObserverCallback, GCHandle.ToIntPtr(handle).ToPointer());
                    CreateRev("A", C4Slice.Constant("1-aa"), Body);
                    _dbCallbackCalls.Should().Be(1, "because we should have received a callback");
                    CreateRev("B", C4Slice.Constant("1-bb"), Body);
                    _dbCallbackCalls.Should().Be(1, "because we should have received a callback");

                    CheckChanges(new[] { "A", "B" }, new[] { "1-aa", "1-bb" });

                    CreateRev("B", C4Slice.Constant("2-bbbb"), Body);
                    _dbCallbackCalls.Should().Be(2, "because we should have received a callback");
                    CreateRev("C", C4Slice.Constant("1-cc"), Body);
                    _dbCallbackCalls.Should().Be(2, "because we should have received a callback");

                    CheckChanges(new[] { "B", "C" }, new[] { "2-bbbb", "1-cc" });
                    Native.c4dbobs_free(_dbObserver);
                    _dbObserver = null;

                    CreateRev("A", C4Slice.Constant("2-aaaa"), Body);
                    _dbCallbackCalls.Should().Be(2, "because the observer was disposed");
                } finally {
                    handle.Free();
                }
            });
        }
Beispiel #6
0
        public void TestInvalidDocID()
        {
            RunTestVariants(() =>
            {
                NativePrivate.c4log_warnOnErrors(false);
                LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
                try {
                    Action <C4Slice> checkPutBadDocID = (C4Slice docID) =>
                    {
                        C4Error e;
                        var rq   = new C4DocPutRequest();
                        rq.body  = Body;
                        rq.save  = true;
                        rq.docID = docID;
                        ((long)Native.c4doc_put(Db, &rq, null, &e)).Should()
                        .Be(0, "because the invalid doc ID should cause the put to fail");
                        e.domain.Should().Be(C4ErrorDomain.LiteCoreDomain);
                        e.code.Should().Be((int)C4ErrorCode.BadDocID);
                    };

                    checkPutBadDocID(C4Slice.Constant(""));
                    string tooLong = new string(Enumerable.Repeat('x', 241).ToArray());
                    using (var tooLong_ = new C4String(tooLong)) {
                        checkPutBadDocID(tooLong_.AsC4Slice());
                    }

                    checkPutBadDocID(C4Slice.Constant("oops\x00oops")); // Bad UTF-8
                    checkPutBadDocID(C4Slice.Constant("oops\noops"));   // Control characters
                } finally {
                    NativePrivate.c4log_warnOnErrors(true);
                    LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err));
                }
            });
        }
Beispiel #7
0
        public void TestImportNames()
        {
            // Docs look like:
            // {"name":{"first":"Travis","last":"Mutchler"},"gender":"female","birthday":"1990-12-21","contact":{"address":{"street":"22 Kansas Cir","zip":"45384","city":"Wilberforce","state":"OH"},"email":["*****@*****.**","*****@*****.**"],"region":"937","phone":["937-3512486"]},"likes":["travelling"],"memberSince":"2010-01-01"}

            RunTestVariants(() => {
                var numDocs = ImportJSONLines("../../../C/tests/data/names_300000.json",
                                              TimeSpan.FromSeconds(15), true);
                var complete = numDocs == 300000;
#if !DEBUG
                numDocs.Should().Be(300000, "because otherwise the operation was too slow");
#endif

                for (int pass = 0; pass < 2; ++pass)
                {
                    var st = Stopwatch.StartNew();
                    var n  = QueryWhere("{\"contact.address.state\": \"WA\"}", true);
                    st.PrintReport("SQL query of state", n, "doc", _output);
                    if (complete)
                    {
                        n.Should().Be(5053, "because that is the number of WA state contact addresses in the document");
                    }

                    if (pass == 0)
                    {
                        var st2 = Stopwatch.StartNew();
                        LiteCoreBridge.Check(err => NativeRaw.c4db_createIndex(Db, C4Slice.Constant("contact.address.state"), C4IndexType.ValueIndex,
                                                                               null, err));
                        st2.PrintReport("Creating SQL index of state", 1, "index", _output);
                    }
                }
            });
        }
        public void TestDeleteIndexedDoc()
        {
            RunTestVariants(() => {
                LiteCoreBridge.Check(err => Native.c4db_createIndex(Db, "test", Json5("[['length()', ['.name.first']]]"),
                                                                    C4IndexType.ValueIndex, null, err));

                // Delete doc "0000015":
                LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
                try {
                    var doc = (C4Document *)LiteCoreBridge.Check(err => Native.c4doc_get(Db, "0000015", true, err));
                    var rq  = new C4DocPutRequest {
                        docID        = C4Slice.Constant("0000015"),
                        history      = &doc->revID,
                        historyCount = 1,
                        revFlags     = C4RevisionFlags.Deleted,
                        save         = true
                    };
                    var updatedDoc = (C4Document *)LiteCoreBridge.Check(err => {
                        var localRq = rq;
                        return(Native.c4doc_put(Db, &localRq, null, err));
                    });

                    Native.c4doc_free(doc);
                    Native.c4doc_free(updatedDoc);
                } finally {
                    LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err));
                }

                // Now run a query that would have returned the deleted doc, if it weren't deleted:
                Compile(Json5("['=', ['length()', ['.name.first']], 9]"));
                Run().Should().Equal(new[] { "0000099" }, "because otherwise the query returned incorrect results");
            });
        }
        public void TestCreateBlobKeyMismatch()
        {
            RunTestVariants(() =>
            {
                var blobToStore            = C4Slice.Constant("This is a blob to store in the store!");
                C4BlobKey key, expectedKey = new C4BlobKey();
                var i = 0;
                foreach (var b in Enumerable.Repeat <byte>(0x55, sizeof(C4BlobKey)))
                {
                    expectedKey.bytes[i++] = b;
                }

                C4Error error;
                NativePrivate.c4log_warnOnErrors(false);
                try {
                    NativeRaw.c4blob_create(_store, blobToStore, &expectedKey, &key, &error).Should().BeFalse();
                    error.domain.Should().Be(C4ErrorDomain.LiteCoreDomain);
                    error.code.Should().Be((int)C4ErrorCode.CorruptData);
                } finally {
                    NativePrivate.c4log_warnOnErrors(true);
                }

                Native.c4blob_keyFromString("sha1-QneWo5IYIQ0ZrbCG0hXPGC6jy7E=", &expectedKey);
                NativeRaw.c4blob_create(_store, blobToStore, &expectedKey, &key, &error).Should().BeTrue();
            });
        }
        private static void TotalAccumulate(object context, C4Key *key, C4Slice value)
        {
            var ctx = context as TotalContext;
            var v   = NativeRaw.FLValue_FromTrustedData((FLSlice)value);

            ctx.total += Native.FLValue_AsDouble(v);
        }
Beispiel #11
0
        private void CreateIndex()
        {
            var ind = (C4Indexer *)LiteCoreBridge.Check(err => Native.c4indexer_begin(Db,
                                                                                      new[] { _view }, err));
            var e = (C4DocEnumerator *)LiteCoreBridge.Check(err => Native.c4indexer_enumerateDocuments(ind, err));

            C4Document *doc;
            C4Error     error;

            while (null != (doc = Native.c4enum_nextDocument(e, &error)))
            {
                var body       = doc->selectedRev.body.CreateString();
                var components = body.Trim('(', ')').Split(',');
                var area       = new C4GeoArea();
                area.xmin = Double.Parse(components[0]);
                area.ymin = Double.Parse(components[1]);
                area.xmax = Double.Parse(components[2]);
                area.ymax = Double.Parse(components[3]);
                var keys   = new C4Key *[1];
                var values = new C4Slice[1];
                keys[0]   = Native.c4key_newGeoJSON("{\"geo\":true}", area);
                values[0] = C4Slice.Constant("1234");
                LiteCoreBridge.Check(err => Native.c4indexer_emit(ind, doc, 0, keys, values, err));
                Native.c4key_free(keys[0]);
                Native.c4doc_free(doc);
            }

            Native.c4enum_free(e);
            error.Code.Should().Be(0, "because otherwise an error occurred somewhere");
            LiteCoreBridge.Check(err => Native.c4indexer_end(ind, true, err));
        }
Beispiel #12
0
        internal void CreateRev(C4Database *db, string docID, C4Slice revID, C4Slice body, C4RevisionFlags flags = (C4RevisionFlags)0)
        {
            LiteCoreBridge.Check(err => Native.c4db_beginTransaction(db, err));
            try {
                var curDoc = (C4Document *)LiteCoreBridge.Check(err => Native.c4doc_get(db, docID,
                                                                                        false, err));
                var history = new[] { revID, curDoc->revID };
                fixed(C4Slice *h = history)
                {
                    var rq = new C4DocPutRequest {
                        existingRevision = true,
                        docID            = curDoc->docID,
                        history          = h,
                        historyCount     = curDoc->revID.buf != null ? 2UL : 1UL,
                        body             = body,
                        revFlags         = flags,
                        save             = true
                    };

                    var doc = (C4Document *)LiteCoreBridge.Check(err => {
                        var localRq = rq;
                        return(Native.c4doc_put(db, &localRq, null, err));
                    });

                    Native.c4doc_free(doc);
                    Native.c4doc_free(curDoc);
                }
            } finally {
                LiteCoreBridge.Check(err => Native.c4db_endTransaction(db, true, err));
            }
        }
Beispiel #13
0
        public void TestCreateRawDoc()
        {
            RunTestVariants(() => {
                var key  = C4Slice.Constant("key");
                var meta = C4Slice.Constant("meta");
                LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
                LiteCoreBridge.Check(err => NativeRaw.c4raw_put(Db, C4Slice.Constant("test"), key, meta,
                                                                Body, err));
                LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err));

                var doc = (C4RawDocument *)LiteCoreBridge.Check(err => NativeRaw.c4raw_get(Db,
                                                                                           C4Slice.Constant("test"), key, err));
                doc->key.Equals(key).Should().BeTrue("because the key should not change");
                doc->meta.Equals(meta).Should().BeTrue("because the meta should not change");
                doc->body.Equals(Body).Should().BeTrue("because the body should not change");
                Native.c4raw_free(doc);

                // Nonexistent:
                C4Error error;
                ((long)Native.c4raw_get(Db, "test", "bogus", &error)).Should().Be(0,
                                                                                  "because the document does not exist");
                error.domain.Should().Be(C4ErrorDomain.LiteCoreDomain, "because that is the correct domain");
                error.code.Should().Be((int)C4ErrorCode.NotFound, "because that is the correct error code");
            });
        }
        public void TestMultiDbObserver()
        {
            RunTestVariants(() => {
                _dbObserver = Native.c4dbobs_create(Db, DBObserverCallback, this);
                CreateRev("A", C4Slice.Constant("1-aa"), Body);
                _dbCallbackCalls.Should().Be(1, "because we should have received a callback");
                CreateRev("B", C4Slice.Constant("1-bb"), Body);
                _dbCallbackCalls.Should().Be(1, "because we should have received a callback");

                CheckChanges(new[] { "A", "B" }, new[] { "1-aa", "1-bb" });

                // Open another database on the same file
                var otherdb = (C4Database *)LiteCoreBridge.Check(err => Native.c4db_open(DatabasePath(), Native.c4db_getConfig(Db), err));
                LiteCoreBridge.Check(err => Native.c4db_beginTransaction(otherdb, err));
                try {
                    CreateRev(otherdb, "C", C4Slice.Constant("1-cc"), Body);
                    CreateRev(otherdb, "D", C4Slice.Constant("1-dd"), Body);
                    CreateRev(otherdb, "E", C4Slice.Constant("1-ee"), Body);
                } finally {
                    LiteCoreBridge.Check(err => Native.c4db_endTransaction(otherdb, true, err));
                }

                _dbCallbackCalls.Should().Be(2, "because the observer should cover all connections");

                CheckChanges(new[] { "C", "D", "E" }, new[] { "1-cc", "1-dd", "1-ee" }, true);
                _dbObserver.Dispose();
                _dbObserver = null;

                CreateRev("A", C4Slice.Constant("2-aaaa"), Body);
                _dbCallbackCalls.Should().Be(2, "because the observer was disposed");

                LiteCoreBridge.Check(err => Native.c4db_close(otherdb, err));
                Native.c4db_free(otherdb);
            });
        }
        public void TestCreateMultipleRevisions()
        {
            RunTestVariants(() => {
                var docID = DocID.CreateString();
                var Body2 = C4Slice.Constant("{\"ok\":\"go\"}");
                CreateRev(docID, RevID, Body);
                CreateRev(docID, Rev2ID, Body2);
                CreateRev(docID, Rev2ID, Body2, false); // test redundant insert

                // Reload the doc:
                var doc = (C4Document *)LiteCoreBridge.Check(err => NativeRaw.c4doc_get(Db, DocID, true, err));
                doc->flags.Should().Be(C4DocumentFlags.Exists);
                doc->docID.Equals(DocID).Should().BeTrue("because the doc should have the stored doc ID");
                doc->revID.Equals(Rev2ID).Should().BeTrue("because the doc should have the current rev ID");
                doc->selectedRev.revID.Equals(Rev2ID).Should().BeTrue("because the current revision is selected");
                doc->selectedRev.sequence.Should().Be(2L, "because the current revision is the second one");
                doc->selectedRev.body.Equals(Body2).Should().BeTrue("because the selected rev should have the correct body");

                if (Versioning == C4DocumentVersioning.RevisionTrees)
                {
                    // Select 1st revision:
                    Native.c4doc_selectParentRevision(doc).Should().BeTrue("because otherwise selecting the parent revision failed");
                    doc->selectedRev.revID.Equals(RevID).Should().BeTrue("because the first revision is selected");
                    doc->selectedRev.sequence.Should().Be(1L, "because the first revision is selected");
                    doc->selectedRev.body.Equals(C4Slice.Null).Should().BeTrue("because the body hasn't been loaded");
                    Native.c4doc_hasRevisionBody(doc).Should().BeTrue("because the body still exists");
                    LiteCoreBridge.Check(err => Native.c4doc_loadRevisionBody(doc, err));
                    doc->selectedRev.body.Equals(Body).Should().BeTrue("because the body is loaded");
                    Native.c4doc_selectParentRevision(doc).Should().BeFalse("because the root revision is selected");
                    Native.c4doc_free(doc);

                    // Compact database:
                    LiteCoreBridge.Check(err => Native.c4db_compact(Db, err));

                    doc = (C4Document *)LiteCoreBridge.Check(err => NativeRaw.c4doc_get(Db, DocID, true, err));
                    Native.c4doc_selectParentRevision(doc).Should().BeTrue("because otherwise selecting the parent revision failed");
                    doc->selectedRev.revID.Equals(RevID).Should().BeTrue("because the first revision is selected");
                    doc->selectedRev.sequence.Should().Be(1L, "because the first revision is selected");
                    if (Storage != C4StorageEngine.SQLite)
                    {
                        doc->selectedRev.body.Equals(C4Slice.Null).Should().BeTrue("because the body is not available");
                        Native.c4doc_hasRevisionBody(doc).Should().BeFalse("because the body has been compacted");
                        C4Error error;
                        Native.c4doc_loadRevisionBody(doc, &error).Should().BeFalse("because the body is unavailable");
                    }

                    LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
                    try {
                        C4Error error;
                        NativeRaw.c4doc_purgeRevision(doc, Rev2ID, &error).Should().Be(2);
                        LiteCoreBridge.Check(err => Native.c4doc_save(doc, 20, err));
                    } finally {
                        LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err));
                    }
                }

                Native.c4doc_free(doc);
            });
        }
Beispiel #16
0
        public void TestCreateMultipleRevisions()
        {
            RunTestVariants(() => {
                C4Slice Body2 = C4Slice.Constant("{\"ok\":\"go\"}");
                C4Slice Body3 = C4Slice.Constant("{\"ubu\":\"roi\"}");
                var docID     = DocID.CreateString();
                CreateRev(docID, RevID, Body);
                CreateRev(docID, Rev2ID, Body2, C4RevisionFlags.KeepBody);
                CreateRev(docID, Rev2ID, Body2); // test redundant Insert

                // Reload the doc:
                var doc = (C4Document *)LiteCoreBridge.Check(err => Native.c4doc_get(Db, docID, true, err));
                doc->flags.Should().HaveFlag(C4DocumentFlags.DocExists, "because the document was saved");
                doc->docID.Should().Equal(DocID, "because the doc ID should save correctly");
                doc->revID.Should().Equal(Rev2ID, "because the doc's rev ID should load correctly");
                doc->selectedRev.revID.Should().Equal(Rev2ID, "because the rev's rev ID should load correctly");
                doc->selectedRev.sequence.Should().Be(2, "because it is the second revision");
                doc->selectedRev.body.Should().Equal(Body2, "because the body should load correctly");

                if (Versioning == C4DocumentVersioning.RevisionTrees)
                {
                    // Select 1st revision:
                    LiteCoreBridge.Check(err => Native.c4doc_selectParentRevision(doc));
                    doc->selectedRev.revID.Should().Equal(RevID, "because now the first revision is selected");
                    doc->selectedRev.sequence.Should().Be(1, "because now the first revision is selected");
                    doc->selectedRev.body.Should().Equal(C4Slice.Null, "because the body of the old revision should be gone");
                    Native.c4doc_hasRevisionBody(doc).Should().BeFalse("because the body of the old revision should be gone");
                    Native.c4doc_selectParentRevision(doc).Should().BeFalse("because a root revision has no parent");
                    Native.c4doc_free(doc);

                    // Add a 3rd revision:
                    CreateRev(docID, Rev3ID, Body3);
                    // Revision 2 should keep its body due to the KeepBody flag
                    doc = (C4Document *)LiteCoreBridge.Check(err => Native.c4doc_get(Db, docID, true, err));
                    Native.c4doc_selectParentRevision(doc).Should().BeTrue("because otherwise the selection of the 2nd revision failed");
                    doc->selectedRev.revID.Should().Equal(Rev2ID, "because the rev's rev ID should load correctly");
                    doc->selectedRev.sequence.Should().Be(2, "because it is the second revision");
                    doc->selectedRev.flags.Should().HaveFlag(C4RevisionFlags.KeepBody, "because the KeepBody flag was saved on the revision");
                    doc->selectedRev.body.Should().Equal(Body2, "because the body should load correctly");
                    Native.c4doc_free(doc);

                    LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
                    try {
                        doc         = (C4Document *)LiteCoreBridge.Check(err => Native.c4doc_get(Db, docID, true, err));
                        var nPurged = NativeRaw.c4doc_purgeRevision(doc, Rev3ID, null);
                        nPurged.Should().Be(3, "because there are three revisions to purge");
                        LiteCoreBridge.Check(err => Native.c4doc_save(doc, 20, err));
                    } finally {
                        LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err));
                        Native.c4doc_free(doc);
                        doc = null;
                    }
                }

                Native.c4doc_free(doc);
            });
        }
Beispiel #17
0
        private static void OnDocError(C4Replicator *repl, bool pushing, C4Slice docID, C4Error error, bool transient, void *context)
        {
            var replicator = GCHandle.FromIntPtr((IntPtr)context).Target as Replicator;

            replicator?.DispatchQueue.DispatchAsync(() =>
            {
                replicator.OnDocError(error, pushing, docID.CreateString() ?? "", transient);
            });
        }
Beispiel #18
0
        public void TestDatabaseRekey()
        {
            RunTestVariants(() =>
            {
                CreateNumberedDocs(99);

                // Add blob to the store:
                var blobToStore = C4Slice.Constant("This is a blob to store in the store!");
                var blobKey     = new C4BlobKey();
                var blobStore   = (C4BlobStore *)LiteCoreBridge.Check(err => Native.c4db_getBlobStore(Db, err));
                LiteCoreBridge.Check(err =>
                {
                    C4BlobKey local;
                    var retVal = NativeRaw.c4blob_create(blobStore, blobToStore, null, &local, err);
                    blobKey    = local;
                    return(retVal);
                });

                C4Error error;
                var blobResult = NativeRaw.c4blob_getContents(blobStore, blobKey, &error);
                ((C4Slice)blobResult).Should().Equal(blobToStore);
                Native.c4slice_free(blobResult);

                // If we're on the unexcrypted pass, encrypt the db.  Otherwise, decrypt it:
                var newKey = new C4EncryptionKey();
                if (Native.c4db_getConfig(Db)->encryptionKey.algorithm == C4EncryptionAlgorithm.None)
                {
                    newKey.algorithm = C4EncryptionAlgorithm.AES256;
                    var keyBytes     = Encoding.ASCII.GetBytes("a different key than default....");
                    Marshal.Copy(keyBytes, 0, (IntPtr)newKey.bytes, 32);
                }

                var tmp = newKey;
                LiteCoreBridge.Check(err =>
                {
                    var local = tmp;
                    return(Native.c4db_rekey(Db, &local, err));
                });

                // Verify the db works:
                Native.c4db_getDocumentCount(Db).Should().Be(99);
                ((IntPtr)blobStore).Should().NotBe(IntPtr.Zero);
                blobResult = NativeRaw.c4blob_getContents(blobStore, blobKey, &error);
                ((C4Slice)blobResult).Should().Equal(blobToStore);
                Native.c4slice_free(blobResult);

                // Check thqat db can be reopened with the new key:
                Native.c4db_getConfig(Db)->encryptionKey.algorithm.Should().Be(newKey.algorithm);
                for (int i = 0; i < 32; i++)
                {
                    Native.c4db_getConfig(Db)->encryptionKey.bytes[i].Should().Be(newKey.bytes[i]);
                }

                ReopenDB();
            });
        }
        private uint IndexLikesView()
        {
            var  likesKey   = Native.FLDictKey_Init("likes", true);
            var  keys       = new[] { Native.c4key_new(), Native.c4key_new(), Native.c4key_new() };
            var  values     = new C4Slice[3];
            uint totalLikes = 0;

            if (_likesView == null)
            {
                _likesView = (C4View *)LiteCoreBridge.Check(err => Native.c4view_open(Db, null, "likes",
                                                                                      "1", Native.c4db_getConfig(Db), err));
            }

            var     views   = new[] { _likesView };
            var     indexer = (C4Indexer *)LiteCoreBridge.Check(err => Native.c4indexer_begin(Db, views, err));
            var     e       = (C4DocEnumerator *)LiteCoreBridge.Check(err => Native.c4indexer_enumerateDocuments(indexer, err));
            C4Error error;

            while (Native.c4enum_next(e, &error))
            {
                var doc   = (C4Document *)LiteCoreBridge.Check(err => Native.c4enum_getDocument(e, err));
                var body  = Native.FLValue_AsDict(NativeRaw.FLValue_FromTrustedData((FLSlice)doc->selectedRev.body));
                var likes = Native.FLValue_AsArray(Native.FLDict_GetWithKey(body, &likesKey));

                FLArrayIterator iter;
                Native.FLArrayIterator_Begin(likes, &iter);
                uint nLikes;
                for (nLikes = 0; nLikes < 3; ++nLikes)
                {
                    var like = NativeRaw.FLValue_AsString(Native.FLArrayIterator_GetValue(&iter));
                    if (like.buf == null)
                    {
                        break;
                    }

                    Native.c4key_reset(keys[nLikes]);
                    NativeRaw.c4key_addString(keys[nLikes], (C4Slice)like);
                    Native.FLArrayIterator_Next(&iter);
                }

                totalLikes += nLikes;
                LiteCoreBridge.Check(err => Native.c4indexer_emit(indexer, doc, 0, nLikes, keys, values, err));
                Native.c4doc_free(doc);
            }

            Native.c4enum_free(e);
            error.Code.Should().Be(0, "because otherwise an error occurred somewhere");
            LiteCoreBridge.Check(err => Native.c4indexer_end(indexer, true, err));
            for (uint i = 0; i < 3; i++)
            {
                Native.c4key_free(keys[i]);
            }

            return(totalLikes);
        }
        internal static unsafe void PinAndUse(this RevisionID revID, Action <C4Slice> action)
        {
            var data = revID.AsData();

            fixed(byte *dataPtr = data)
            {
                var slice = new C4Slice(dataPtr, (uint)data.Length);

                action(slice);
            }
        }
Beispiel #21
0
        public void TestDuplicateRev()
        {
            RunTestVariants(() =>
            {
                var docID = "mydoc";
                var body  = "{\"key\":\"value\"}";
                var doc   = PutDoc(docID, null, body);
                var revID = doc->revID.CreateString();
                Native.c4doc_free(doc);

                body        = "{\"key\":\"newvalue\"}";
                doc         = PutDoc(docID, revID, body);
                var revID2a = doc->revID.CreateString();
                Native.c4doc_free(doc);

                LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
                var success = false;
                try {
                    using (var docID_ = new C4String(docID))
                        using (var revID_ = new C4String(revID))
                            using (var body_ = new C4String(body)) {
                                var history = new C4Slice[] { revID_.AsC4Slice() };
                                fixed(C4Slice * history_ = history)
                                {
                                    var rq = new C4DocPutRequest
                                    {
                                        allowConflict = true,
                                        docID         = docID_.AsC4Slice(),
                                        history       = history_,
                                        historyCount  = 1,
                                        body          = body_.AsC4Slice(),
                                        revFlags      = 0,
                                        save          = true
                                    };

                                    doc = (C4Document *)LiteCoreBridge.Check(err =>
                                    {
                                        var local = rq;
                                        return(Native.c4doc_put(Db, &local, null, err));
                                    });

                                    doc->docID.CreateString().Should().Be(docID);
                                }
                            }
                } finally {
                    LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, success, err));
                }

                var revID2b = doc->revID.CreateString();
                Native.c4doc_free(doc);

                revID2b.Should().Be(revID2a, "because an identical revision was inserted");
            });
        }
        public void TestDocObserver()
        {
            RunTestVariants(() => {
                CreateRev("A", C4Slice.Constant("1-aa"), Body);
                _docObserver = Native.c4docobs_create(Db, "A", DocObserverCallback, this);

                CreateRev("A", C4Slice.Constant("2-bb"), Body);
                CreateRev("B", C4Slice.Constant("1-bb"), Body);
                _docCallbackCalls.Should().Be(1, "because there was only one update to the doc in question");
            });
        }
Beispiel #23
0
        static Test()
        {
            var enc = Native.FLEncoder_New();

            Native.FLEncoder_BeginDict(enc, 1);
            Native.FLEncoder_WriteKey(enc, "answer");
            Native.FLEncoder_WriteInt(enc, 42);
            Native.FLEncoder_EndDict(enc);
            var result = NativeRaw.FLEncoder_Finish(enc, null);

            FleeceBody = result;
        }
Beispiel #24
0
        public void TestDatabaseCompact()
        {
            RunTestVariants(() =>
            {
                var doc1ID   = C4Slice.Constant("doc001");
                var doc2ID   = C4Slice.Constant("doc002");
                var doc3ID   = C4Slice.Constant("doc003");
                var content1 = "This is the first attachment";
                var content2 = "This is the second attachment";

                var atts = new List <string>();
                C4BlobKey key1, key2;
                atts.Add(content1);
                LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err));
                try {
                    key1 = AddDocWithAttachments(doc1ID, atts, "text/plain")[0];
                    atts.Clear();
                    atts.Add(content2);
                    key2 = AddDocWithAttachments(doc2ID, atts, "text/plain")[0];
                    AddDocWithAttachments(doc3ID, atts, "text/plain");
                } finally {
                    LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err));
                }

                var store = (C4BlobStore *)LiteCoreBridge.Check(err => Native.c4db_getBlobStore(Db, err));
                LiteCoreBridge.Check(err => Native.c4db_compact(Db, err));
                Native.c4blob_getSize(store, key1).Should()
                .BeGreaterThan(0, "because the attachment should survive the first compact");
                Native.c4blob_getSize(store, key2).Should()
                .BeGreaterThan(0, "because the attachment should survive the first compact");

                CreateRev("doc001", Rev2ID, C4Slice.Null, C4RevisionFlags.Deleted);
                LiteCoreBridge.Check(err => Native.c4db_compact(Db, err));
                Native.c4blob_getSize(store, key1).Should().Be(-1,
                                                               "because the attachment should be collected in the second compact");
                Native.c4blob_getSize(store, key2).Should()
                .BeGreaterThan(0, "because the attachment should survive the second compact");

                CreateRev("doc002", Rev2ID, C4Slice.Null, C4RevisionFlags.Deleted);
                LiteCoreBridge.Check(err => Native.c4db_compact(Db, err));
                Native.c4blob_getSize(store, key1).Should().Be(-1,
                                                               "because the attachment should still be gone in the third compact");
                Native.c4blob_getSize(store, key2).Should()
                .BeGreaterThan(0, "because the attachment should survive the third compact");

                CreateRev("doc003", Rev2ID, C4Slice.Null, C4RevisionFlags.Deleted);
                LiteCoreBridge.Check(err => Native.c4db_compact(Db, err));
                Native.c4blob_getSize(store, key1).Should().Be(-1,
                                                               "because the attachment should still be gone in the fourth compact");
                Native.c4blob_getSize(store, key2).Should().Be(-1,
                                                               "because the attachment should be collected in the fourth compact");
            });
        }
Beispiel #25
0
 static Test()
 {
     #if NETCOREAPP1_0
     LoadDLL();
     #endif
     var enc = Native.FLEncoder_New();
     Native.FLEncoder_BeginDict(enc, 1);
     Native.FLEncoder_WriteKey(enc, "answer");
     Native.FLEncoder_WriteInt(enc, 42);
     Native.FLEncoder_EndDict(enc);
     var result = NativeRaw.FLEncoder_Finish(enc, null);
     FleeceBody = result;
 }
Beispiel #26
0
 static Test()
 {
     #if NETCOREAPP2_0
     Couchbase.Lite.Support.NetDesktop.Activate();
     #endif
     var enc = Native.FLEncoder_New();
     Native.FLEncoder_BeginDict(enc, 1);
     Native.FLEncoder_WriteKey(enc, "answer");
     Native.FLEncoder_WriteInt(enc, 42);
     Native.FLEncoder_EndDict(enc);
     var result = NativeRaw.FLEncoder_Finish(enc, null);
     FleeceBody = (C4Slice)result;
 }
        private C4Document *PutDoc(C4Database *db, string docID, string revID, string body, C4RevisionFlags flags, C4Error *error = null)
        {
            LiteCoreBridge.Check(err => Native.c4db_beginTransaction(db, err));
            var success = false;

            try {
                using (var docID_ = new C4String(docID))
                    using (var revID_ = new C4String(revID))
                        using (var body_ = new C4String(body)) {
                            var history = new C4Slice[] { revID_.AsC4Slice() };
                            fixed(C4Slice *history_ = history)
                            {
                                var rq = new C4DocPutRequest
                                {
                                    allowConflict = false,
                                    docID         = docID_.AsC4Slice(),
                                    history       = revID == null ? null : history_,
                                    historyCount  = revID == null ? 0UL : 1UL,
                                    body          = body_.AsC4Slice(),
                                    revFlags      = flags,
                                    remoteDBID    = _remoteDocID,
                                    save          = true
                                };

                                C4Document *doc;

                                if (error != null)
                                {
                                    var local = rq;
                                    doc = Native.c4doc_put(db, &local, null, error);
                                }
                                else
                                {
                                    doc = (C4Document *)LiteCoreBridge.Check(err =>
                                    {
                                        var local = rq;
                                        return(Native.c4doc_put(db, &local, null, err));
                                    });
                                }

                                success = true;
                                return(doc);
                            }
                        }
            } finally {
                LiteCoreBridge.Check(err => Native.c4db_endTransaction(db, success, err));
            }
        }
        private void CreateFullTextIndex(uint docCount)
        {
            for (uint i = 1; i <= docCount; i++)
            {
                string docID = $"doc-{i:D3}";
                var    body  = C4Slice.Null;
                switch (i % 3)
                {
                case 0:
                    body = C4Slice.Constant("The cat sat on the mat");
                    break;

                case 1:
                    body = C4Slice.Constant("Outside SomeWhere a c\u00e4t was barking");
                    break;

                case 2:
                    body = C4Slice.Constant("The bark of a tree is rough?");
                    break;
                }

                CreateRev(docID, RevID, body);
            }

            var ind = (C4Indexer *)LiteCoreBridge.Check(err => Native.c4indexer_begin(Db,
                                                                                      new[] { _view }, err));
            var e = (C4DocEnumerator *)LiteCoreBridge.Check(err => Native.c4indexer_enumerateDocuments(ind, err));

            C4Document *doc;
            C4Error     error;

            while (null != (doc = Native.c4enum_nextDocument(e, &error)))
            {
                // Index 'doc':
                var keys   = new C4Key *[1];
                var values = new C4Slice[1];
                keys[0]   = NativeRaw.c4key_newFullTextString(doc->selectedRev.body, C4Slice.Constant("en"));
                values[0] = C4Slice.Constant("1234");
                LiteCoreBridge.Check(err => Native.c4indexer_emit(ind, doc, 0, keys, values, err));
                Native.c4key_free(keys[0]);
                Native.c4doc_free(doc);
            }

            error.Code.Should().Be(0, "because otherwise an error occurred somewhere");
            Native.c4enum_free(e);
            LiteCoreBridge.Check(err => Native.c4indexer_end(ind, true, err));
        }
Beispiel #29
0
        public void TestDocObserver()
        {
            RunTestVariants(() => {
                var handle = GCHandle.Alloc(this);
                try {
                    CreateRev("A", C4Slice.Constant("1-aa"), Body);
                    _docObserver = Native.c4docobs_create(Db, "A", DocObserverCallback,
                                                          GCHandle.ToIntPtr(handle).ToPointer());

                    CreateRev("A", C4Slice.Constant("2-bb"), Body);
                    CreateRev("B", C4Slice.Constant("1-bb"), Body);
                    _docCallbackCalls.Should().Be(1, "because there was only one update to the doc in question");
                } finally {
                    handle.Free();
                }
            });
        }
Beispiel #30
0
        internal C4BlobKey[] AddDocWithAttachments(C4Slice docID, List <string> atts, string contentType)
        {
            var keys = new List <C4BlobKey>();
            var json = new StringBuilder();

            json.Append("{attached: [");
            foreach (var att in atts)
            {
                var key = new C4BlobKey();
                LiteCoreBridge.Check(err =>
                {
                    var localKey = key;
                    var retVal   = Native.c4blob_create(Native.c4db_getBlobStore(Db, null), Encoding.UTF8.GetBytes(att),
                                                        null, &localKey, err);
                    key = localKey;
                    return(retVal);
                });

                keys.Add(key);
                var keyStr = Native.c4blob_keyToString(key);
                json.Append(
                    $"{{'{Constants.ObjectTypeProperty}': '{Constants.ObjectTypeBlob}', 'digest': '{keyStr}', length: {att.Length}, 'content_type': '{contentType}'}},");
            }

            json.Append("]}");
            var jsonStr = Native.FLJSON5_ToJSON(json.ToString(), null);

            using (var jsonStr_ = new C4String(jsonStr)) {
                C4Error error;
                var     body = NativeRaw.c4db_encodeJSON(Db, jsonStr_.AsC4Slice(), &error);
                ((long)body.buf).Should().NotBe(0, "because otherwise the encode failed");

                var rq = new C4DocPutRequest();
                rq.docID    = docID;
                rq.revFlags = C4RevisionFlags.HasAttachments;
                rq.body     = (C4Slice)body;
                rq.save     = true;
                var doc = Native.c4doc_put(Db, &rq, null, &error);
                Native.c4slice_free(body);
                ((long)doc).Should().NotBe(0, "because otherwise the put failed");
                Native.c4doc_free(doc);
                return(keys.ToArray());
            }
        }
Beispiel #31
0
 private static void c4log_wedge(C4LogLevel level, C4Slice message)
 {
     if (_LogCallback != null) {
         var sharpString = (string)message;
         _LogCallback(level, sharpString);
     }
 }
Beispiel #32
0
 /// <summary>
 /// Emits new keys/values derived from one document, for one view.
 /// This function needs to be called once for each(document, view) pair.Even if the view's map
 /// function didn't emit anything, the old keys/values need to be cleaned up.
 ///      
 /// Values are uninterpreted by CBForest, but by convention are JSON. A special value "*"
 /// (a single asterisk) is used as a placeholder for the entire document.
 ///
 /// </summary>
 /// <param name="indexer">The indexer to operate on</param>
 /// <param name="document">The document being indexed</param>
 /// <param name="viewNumber">The position of the view in the indexer's views[] array</param>
 /// <param name="emittedKeys">Array of keys being emitted</param>
 /// <param name="emittedValues">Array of values being emitted. (JSON by convention.)</param>
 /// <param name="outError">The error that occurred if the operation doesn't succeed</param>
 /// <returns>true on success, false otherwise</returns>
 public static bool c4indexer_emit(C4Indexer *indexer, C4Document *document, uint viewNumber,
     C4Key*[] emittedKeys, C4Slice[] emittedValues, C4Error *outError)
 {
     fixed(C4Key** keysPtr = emittedKeys)
     fixed(C4Slice* valuesPtr = emittedValues)
     {
         return c4indexer_emit(indexer, document, viewNumber, (uint)emittedKeys.Length, keysPtr, valuesPtr, outError);
     }
 }
Beispiel #33
0
 public static extern bool c4raw_put(C4Database *db, C4Slice storeName, C4Slice key, C4Slice meta,
     C4Slice body, C4Error *outError);
Beispiel #34
0
 private static extern C4RawDocument* _c4raw_get(C4Database *db, C4Slice storeName, C4Slice docID, C4Error *outError);
Beispiel #35
0
 public static extern int c4doc_insertRevisionWithHistory(C4Document *doc, C4Slice body, 
     [MarshalAs(UnmanagedType.U1)]bool deleted, [MarshalAs(UnmanagedType.U1)]bool hasAttachments, C4Slice* history, 
     uint historyCount, C4Error *outError);
Beispiel #36
0
 private static void Log(C4LogLevel level, C4Slice message)
 {
     string[] levelNames = new[] { "debug", "info", "WARNING", "ERROR" };
     Console.Error.WriteLineAsync(String.Format("CBForest-C {0}: {1}", levelNames[(int)level], (string)message));
 }
Beispiel #37
0
 public static extern void c4key_addString(C4Key *key, C4Slice s);
Beispiel #38
0
 private static extern C4View* _c4view_open(C4Database *db, C4Slice path, C4Slice viewName, C4Slice version, 
     C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError);
Beispiel #39
0
        public static C4Key* c4key_withBytes(C4Slice slice)
        {
            #if DEBUG
            var retVal = _c4key_withBytes(slice);
            if(retVal != null) {
                _AllocatedObjects[(IntPtr)retVal] = "C4Key";
                #if ENABLE_LOGGING
                Console.WriteLine("[c4key_withBytes] Allocated 0x{0}", ((IntPtr)retVal).ToString("X"));
                #endif
            }

            return retVal;
            #else
            return _c4key_withBytes(slice);
            #endif
        }
Beispiel #40
0
 /// <summary>
 /// Creates a C4Key by copying the data, which must be in the C4Key binary format.
 /// </summary>
 /// <param name="bytes">The data to use in the C4Key</param>
 /// <returns>A pointer to the created C4Key</returns>
 public static C4Key* c4key_withBytes(IEnumerable<byte> bytes)
 {
     var realized = bytes.ToArray();
     fixed(byte* ptr = realized) {
         var slice = new C4Slice(ptr, (uint)realized.Length);
         return c4key_withBytes(slice);
     }
 }
Beispiel #41
0
 private static extern C4Key* _c4key_withBytes(C4Slice slice);
Beispiel #42
0
 public static extern int c4doc_purgeRevision(C4Document *doc, C4Slice revId, C4Error *outError);
Beispiel #43
0
 public static extern bool c4doc_setType(C4Document *doc, C4Slice docType, C4Error *outError);
Beispiel #44
0
 public static extern bool c4doc_selectRevision(C4Document *doc, C4Slice revID, [MarshalAs(UnmanagedType.U1)]bool withBody, 
     C4Error *outError);
Beispiel #45
0
        /// <summary>
        /// Reads a raw document from the database. In Couchbase Lite the store named "info" is used for 
        /// per-database key/value pairs, and the store "_local" is used for local documents.
        /// </summary>
        /// <param name="db">The database to operate on</param>
        /// <param name="storeName">The name of the store to read from</param>
        /// <param name="docID">The ID of the document to retrieve</param>
        /// <param name="outError">The error that occurred if the operation doesn't succeed</param>
        /// <returns>A pointer to the retrieved document on success, or null on failure</returns>
        public static C4RawDocument* c4raw_get(C4Database *db, C4Slice storeName, C4Slice docID, C4Error *outError)
        {
            #if DEBUG
            var retVal = _c4raw_get(db, storeName, docID, outError);
            if(retVal != null) {
                _AllocatedObjects.TryAdd((IntPtr)retVal, "C4RawDocument");
                #if ENABLE_LOGGING
                Console.WriteLine("[c4raw_get] Allocated 0x{0}", ((IntPtr)retVal).ToString("X"));
                #endif
            }

            return retVal;
            #else
            return _c4raw_get(db, storeName, docID, outError);
            #endif
        }
Beispiel #46
0
 public static extern bool c4indexer_emit(C4Indexer *indexer, C4Document *document, uint viewNumber, uint emitCount,
     C4Key** emittedKeys, C4Slice* emittedValues, C4Error *outError);
Beispiel #47
0
 public static extern bool c4db_purgeDoc(C4Database *db, C4Slice docId, C4Error *outError);
Beispiel #48
0
 private static extern void c4key_addMapKey(C4Key *key, C4Slice s);
Beispiel #49
0
 public static extern int c4doc_insertRevision(C4Document *doc, C4Slice revID, C4Slice body, 
     [MarshalAs(UnmanagedType.U1)]bool deleted, [MarshalAs(UnmanagedType.U1)]bool hasAttachments,
     [MarshalAs(UnmanagedType.U1)]bool allowConflict, C4Error *outError);
Beispiel #50
0
        /// <summary>
        /// Opens a view, or creates it if the file doesn't already exist.
        /// </summary>
        /// <param name="db">The database the view is associated with</param>
        /// <param name="path">The file that the view is stored in</param>
        /// <param name="viewName">The name of the view</param>
        /// <param name="version">The version of the view's map function</param>
        /// <param name="flags">The flags for opening the view file</param>
        /// <param name="encryptionKey">The option encryption key used to encrypt the database</param>
        /// <param name="outError">The error that occurred if the operation doesn't succeed</param>
        /// <returns>A pointer to the view on success, otherwise null</returns>
        public static C4View* c4view_open(C4Database *db, C4Slice path, C4Slice viewName, C4Slice version, 
            C4DatabaseFlags flags, C4EncryptionKey *encryptionKey, C4Error *outError)
        {
            #if DEBUG
            var retVal = _c4view_open(db, path, viewName, version, flags, encryptionKey, outError);
            if(retVal != null) {
                _AllocatedObjects.TryAdd((IntPtr)retVal, "C4View");
                #if ENABLE_LOGGING
                Console.WriteLine("[c4view_open] Allocated 0x{0}", ((IntPtr)retVal).ToString("X"));
                #endif
            }

            return retVal;
            #else
            return _c4view_open(db, path, viewName, version, flags, encryptionKey, outError);
            #endif
        }
Beispiel #51
0
 private static extern C4DocEnumerator* _c4db_enumerateAllDocs(C4Database *db, C4Slice startDocID, C4Slice endDocID, 
     C4EnumeratorOptions *options, C4Error *outError);
Beispiel #52
0
 public static extern void c4key_addMapKey(C4Key *key, C4Slice s);
Beispiel #53
0
        public static C4Document* c4doc_get(C4Database *db, C4Slice docID, bool mustExist, 
            C4Error *outError)
        {
            #if DEBUG
            var retVal = _c4doc_get(db, docID, mustExist, outError);
            if(retVal != null) {
                _AllocatedObjects[(IntPtr)retVal] = "C4Document";
                #if ENABLE_LOGGING
                Console.WriteLine("[c4doc_get] Allocated 0x{0}", ((IntPtr)retVal).ToString("X"));
                #endif
            }

            return retVal;
            #else
            return _c4doc_get(db, docID, mustExist, outError);
            #endif
        }
Beispiel #54
0
 public static extern void c4slice_free(C4Slice slice);
Beispiel #55
0
        public static C4DocEnumerator* c4db_enumerateAllDocs(C4Database *db, C4Slice startDocID, C4Slice endDocID, 
            C4EnumeratorOptions *options, C4Error *outError)
        {
            #if DEBUG
            var retVal = _c4db_enumerateAllDocs(db, startDocID, endDocID, options, outError);
            if(retVal != null) {
                _AllocatedObjects[(IntPtr)retVal] = "C4DocEnumerator";
                #if ENABLE_LOGGING
                Console.WriteLine("[c4db_enumerateAllDocs] Allocated 0x{0}", ((IntPtr)retVal).ToString("X"));
                #endif
            }

            return retVal;
            #else
            return _c4db_enumerateAllDocs(db, startDocID, endDocID, options, outError);
            #endif
        }
Beispiel #56
0
 private static extern C4Database* _c4db_open(C4Slice path, C4DatabaseFlags flags, 
     C4EncryptionKey *encryptionKey, C4Error *outError);
Beispiel #57
0
        public static C4Database* c4db_open(C4Slice path, C4DatabaseFlags flags, 
            C4EncryptionKey *encryptionKey, C4Error *outError)
        {
            #if DEBUG
            var retVal = _c4db_open(path, flags, encryptionKey, outError);
            if(retVal != null) {
                _AllocatedObjects[(IntPtr)retVal] = "C4Database";
                #if ENABLE_LOGGING
                Console.WriteLine("[c4db_open] Allocated 0x{0}", ((IntPtr)retVal).ToString("X"));
                #endif
            }

            return retVal;
            #else
            return _c4db_open(path, flags, encryptionKey, outError);
            #endif
        }
Beispiel #58
0
 private static extern C4DocEnumerator* _c4db_enumerateSomeDocs(C4Database *db, C4Slice* docIDs, uint docIDsCount, 
     C4EnumeratorOptions *options, C4Error *outError);
Beispiel #59
0
 private static extern C4Document* _c4doc_get(C4Database *db, C4Slice docID, [MarshalAs(UnmanagedType.U1)]bool mustExist, 
     C4Error *outError);