private void ObserverTask()
        {
            var database = OpenDB();
            var handle   = GCHandle.Alloc(this);
            C4DatabaseObserverCallback callback = ObsCallback;
            var observer     = Native.c4dbobs_create(database, callback, GCHandle.ToIntPtr(handle).ToPointer());
            var lastSequence = 0UL;

            try {
                do
                {
                    lock (_observerMutex)
                    {
                        if (!_changesToObserve)
                        {
                            continue;
                        }

                        Write("8");
                        _changesToObserve = false;
                    }

                    var  changes = new C4DatabaseChange[10];
                    uint nDocs;
                    bool external;
                    while (0 < (nDocs = Native.c4dbobs_getChanges(observer, changes, 10U, &external)))
                    {
                        try
                        {
                            external.Should().BeTrue("because all changes will be external in this test");
                            for (int i = 0; i < nDocs; ++i)
                            {
                                changes[i].docID.CreateString().Should().StartWith("doc-",
                                                                                   "because otherwise the document ID is not what we created");
                                lastSequence = changes[i].sequence;
                            }
                        }
                        finally
                        {
                            Native.c4dbobs_releaseChanges(changes, nDocs);
                        }
                    }

                    Task.Delay(TimeSpan.FromMilliseconds(100)).Wait();
                } while (lastSequence < NumDocs);
            } finally {
                Native.c4dbobs_free(observer);
                handle.Free();
                CloseDB(database);
            }
        }
        private void CheckChanges(IList <string> expectedDocIDs, IList <string> expectedRevIDs, bool expectedExternal = false)
        {
            var  changes = new C4DatabaseChange[100];
            bool external;
            var  changeCount = Native.c4dbobs_getChanges(_dbObserver.Observer, changes, 100, &external);

            changeCount.Should().Be((uint)expectedDocIDs.Count, "because otherwise we didn't get the correct number of changes");
            for (int i = 0; i < changeCount; i++)
            {
                changes[i].docID.CreateString().Should().Be(expectedDocIDs[i], "because otherwise we have an invalid document ID");
                changes[i].revID.CreateString().Should().Be(expectedRevIDs[i], "because otherwise we have an invalid document revision ID");
            }

            external.Should().Be(expectedExternal, "because otherwise the external parameter was wrong");
        }
Example #3
0
        private void PostDatabaseChanged()
        {
            var allChanges = new List <DatabaseChangedEventArgs>();

            ThreadSafety.DoLocked(() =>
            {
                if (_obs == null || _c4db == null || InTransaction)
                {
                    return;
                }

                const uint maxChanges = 100u;
                var external          = false;
                uint nChanges;
                var changes = new C4DatabaseChange[maxChanges];
                var docIDs  = new List <string>();
                do
                {
                    // Read changes in batches of MaxChanges:
                    bool newExternal;
                    nChanges = Native.c4dbobs_getChanges(_obs.Observer, changes, maxChanges, &newExternal);
                    if (nChanges == 0 || external != newExternal || docIDs.Count > 1000)
                    {
                        if (docIDs.Count > 0)
                        {
                            // Only notify if there are actually changes to send
                            var args = new DatabaseChangedEventArgs(this, docIDs);
                            allChanges.Add(args);
                            docIDs = new List <string>();
                        }
                    }

                    external = newExternal;
                    for (var i = 0; i < nChanges; i++)
                    {
                        docIDs.Add(changes[i].docID.CreateString());
                    }
                } while (nChanges > 0);
            });

            foreach (var args in allChanges)
            {
                _databaseChanged.Fire(this, args);
            }
        }
        private void ObserverTask()
        {
            var database     = OpenDB();
            var observer     = Native.c4dbobs_create(database, ObsCallback, this);
            var lastSequence = 0UL;

            do
            {
                lock (_observerMutex) {
                    if (!_changesToObserve)
                    {
                        continue;
                    }

                    Write("8");
                    _changesToObserve = false;
                }

                var  changes = new C4DatabaseChange[10];
                uint nDocs;
                bool external;
                while (0 < (nDocs = Native.c4dbobs_getChanges(observer.Observer, changes, 10U, &external)))
                {
                    external.Should().BeTrue("because all changes will be external in this test");
                    for (int i = 0; i < nDocs; ++i)
                    {
                        changes[i].docID.CreateString().Should().StartWith("doc-", "because otherwise the document ID is not what we created");
                        lastSequence = changes[i].sequence;
                    }
                }

                Task.Delay(TimeSpan.FromMilliseconds(100)).Wait();
            } while (lastSequence < NumDocs);

            observer.Dispose();
            CloseDB(database);
        }