public void TestDBObserver() { RunTestVariants(() => { var handle = GCHandle.Alloc(this); try { _dbObserver = Native.c4dbobs_create(Db, DatabaseCallback, GCHandle.ToIntPtr(handle).ToPointer()); CreateRev("A", FLSlice.Constant("1-aa"), FleeceBody); _dbCallbackCalls.Should().Be(1, "because we should have received a callback"); CreateRev("B", FLSlice.Constant("1-bb"), FleeceBody); _dbCallbackCalls.Should().Be(1, "because we should have received a callback"); CheckChanges(new[] { "A", "B" }, new[] { "1-aa", "1-bb" }); CreateRev("B", FLSlice.Constant("2-bbbb"), FleeceBody); _dbCallbackCalls.Should().Be(2, "because we should have received a callback"); CreateRev("C", FLSlice.Constant("1-cc"), FleeceBody); _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", FLSlice.Constant("2-aaaa"), FleeceBody); _dbCallbackCalls.Should().Be(2, "because the observer was disposed"); } finally { handle.Free(); } }); }
private void Observe(C4DatabaseObserver *observer) { Write("!"); lock (_observerMutex) { _changesToObserve = true; } }
private static void DbObserverCallback(C4DatabaseObserver *db, object context) { var dbObj = (Database)context; dbObj?._callbackFactory.StartNew(() => { dbObj.PostDatabaseChanged(); }); }
private static void DbObserverCallback(C4DatabaseObserver *observer, void *context) { var idHolder = GCHandle.FromIntPtr((IntPtr)context); var id = (Guid)idHolder.Target; var obj = _ObserverMap[id]; obj._callback?.Invoke(observer, obj._context); }
protected override void TeardownVariant(int option) { Native.c4dbobs_free(_dbObserver); _dbObserver = null; Native.c4docobs_free(_docObserver); _docObserver = null; base.TeardownVariant(option); }
public void TestMultiDbObserver() { RunTestVariants(() => { var handle = GCHandle.Alloc(this); try { _dbObserver = Native.c4dbobs_create(Db, DatabaseCallback, GCHandle.ToIntPtr(handle).ToPointer()); CreateRev("A", FLSlice.Constant("1-aa"), FleeceBody); _dbCallbackCalls.Should().Be(1, "because we should have received a callback"); CreateRev("B", FLSlice.Constant("1-bb"), FleeceBody); _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", FLSlice.Constant("1-cc"), FleeceBody); CreateRev(otherdb, "D", FLSlice.Constant("1-dd"), FleeceBody); CreateRev(otherdb, "E", FLSlice.Constant("1-ee"), FleeceBody); } 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); Native.c4dbobs_free(_dbObserver); _dbObserver = null; CreateRev("A", FLSlice.Constant("2-aaaa"), FleeceBody); _dbCallbackCalls.Should().Be(2, "because the observer was disposed"); LiteCoreBridge.Check(err => Native.c4db_close(otherdb, err)); Native.c4db_release(otherdb); } finally { handle.Free(); } }); }
private static void ObsCallback(C4DatabaseObserver *observer, object context) { ((ThreadingTest)context).Observe(observer); }
public static extern uint c4dbobs_getChanges(C4DatabaseObserver *observer, [Out] C4DatabaseChange[] outChanges, uint maxChanges, bool *outExternal);
public static extern void c4dbobs_free(C4DatabaseObserver *observer);
private static void ObsCallback(C4DatabaseObserver *observer, void *context) { var obj = GCHandle.FromIntPtr((IntPtr)context).Target as ThreadingTest; obj.Observe(observer); }
private void DbObserverCalled(C4DatabaseObserver *obs) { ((long)obs).Should().Be((long)_dbObserver, "because the callback should be for the proper DB"); _dbCallbackCalls++; }
private static void DBObserverCallback(C4DatabaseObserver *obs, void *context) { var obj = GCHandle.FromIntPtr((IntPtr)context).Target as ObserverTest; obj.DbObserverCalled(obs); }
public void c4dbobs_free(C4DatabaseObserver *observer) => Native.c4dbobs_free(observer);
public uint c4dbobs_getChanges(C4DatabaseObserver *observer, C4DatabaseChange[] outChanges, uint maxChanges, bool *outExternal) => Native.c4dbobs_getChanges(observer, outChanges, maxChanges, outExternal);
public static void c4dbobs_free(C4DatabaseObserver *observer) => Impl.c4dbobs_free(observer);
private static void DBObserverCallback(C4DatabaseObserver *obs, object context) { ((ObserverTest)context).DbObserverCalled(obs); }