예제 #1
0
        public void TestSession42_ReplicateSimple()
        {
            // close replica we just created and attach db file to our primary db as "replica"
            dbReplica.Close();
            dbPrimary.AttachDB(dbReplicaPath, "replica");

            // verify that "main" has rows in TestTable1 and "replica" currently empty
            var mainTestTable1Rows = dbPrimary.Query <TestTable1>("Select * FROM main.TestTable1;");

            Assert.That(mainTestTable1Rows.Count, Is.GreaterThan(0));

            var replicaTestTable1Rows = dbPrimary.Query <TestTable1>("Select * FROM replica.TestTable1;");

            Assert.That(replicaTestTable1Rows.Count, Is.EqualTo(0));

            // create a session for "main" database
            Assert.That(dbPrimary.CreateSession("main", out session), Is.EqualTo(SQLite3.Result.OK));

            // attach all tables [from "main"] to it
            Assert.That(SQLiteSession.AttachToTable(session, null), Is.EqualTo(SQLite3.Result.OK));

            // Note: we have not enabled watching for changes

            // validate no changes have occurred
            Assert.That(SQLiteSession.IsEmptySession(session), Is.True);

            // see what it would take to make replica.table like main.table
#pragma warning disable IDE0018 // Inline variable declaration
            string errMsg;
#pragma warning restore IDE0018 // Inline variable declaration
            Assert.That(SQLiteSession.AddTableDiffToSession(session, "replica", nameof(TestTable1), out errMsg), Is.EqualTo(SQLite3.Result.OK));
            Assert.That(SQLiteSession.AddTableDiffToSession(session, "replica", nameof(TestTable2), out errMsg), Is.EqualTo(SQLite3.Result.OK));

            // session should no longer be empty, as tables differ and session should have the diff
            Assert.That(SQLiteSession.IsEmptySession(session), Is.False);

            // create change set
            Assert.That(SQLiteSession.GenerateChangeSet(session, out SQLiteChangeSet changeSet), Is.EqualTo(SQLite3.Result.OK));

            // done with our session
            SQLiteSession.Delete(session);

            // remove secondary db
            dbPrimary.DetachDB("replica");

            // reopen dbReplica
            dbReplica = new SQLiteConnection(dbReplicaPath, storeDateTimeAsTicks: true);

            // validate reopened replica db has no rows
            replicaTestTable1Rows = dbReplica.Query <TestTable1>("Select * FROM TestTable1;");
            Assert.That(replicaTestTable1Rows.Count, Is.EqualTo(0));

            // apply change set to dbReplica
            // should be no conflicts so conflict handler not called
            Assert.That(dbReplica.ApplySessionChangeSet(changeSet, null, null, null), Is.EqualTo(SQLite3.Result.OK));

            // validate has contents we expect
            replicaTestTable1Rows = dbReplica.Query <TestTable1>("Select * FROM TestTable1;");
            Assert.That(replicaTestTable1Rows.Count, Is.GreaterThan(0));

            // generate inverse change set
            Assert.That(SQLiteSession.InvertChangeSet(changeSet, out SQLiteChangeSet inverseChangeSet), Is.EqualTo(SQLite3.Result.OK));
            using (inverseChangeSet)
            {
                // apply the inverse
                Assert.That(dbReplica.ApplySessionChangeSet(inverseChangeSet, null, null, null), Is.EqualTo(SQLite3.Result.OK));

                // validate replica db once again has no rows
                replicaTestTable1Rows = dbReplica.Query <TestTable1>("Select * FROM TestTable1;");
                Assert.That(replicaTestTable1Rows.Count, Is.EqualTo(0));
            }

            // reset
            CleanupTest();
            SetupTest();

            // insert differing row to dbReplica with same primary key, i.e. force conflict
            // add a row to table
            var newRow = new TestTable1
            {
                pk             = sampleData.pk,
                myString       = "test conflict", // <== only conflicting piece of data
                myInt          = sampleData.myInt,
                myDate         = sampleData.myDate,
                myTable2Object = sampleData.myTable2Object
            };
            Assert.That(dbReplica.Insert(newRow), Is.EqualTo(1));

            // apply change set to dbReplica
            // should now be a conflict so conflict handler is called
            Assert.That(dbReplica.ApplySessionChangeSet(changeSet, DummyFilterCallback /* null */, SQLiteSession.CallbackReplaceOnConflicts, null /*"my text context"*/), Is.EqualTo(SQLite3.Result.OK));

            // valid has contents we expect
            replicaTestTable1Rows = dbReplica.Query <TestTable1>("Select * FROM TestTable1;");
            Assert.That(replicaTestTable1Rows.Count, Is.GreaterThan(0));

            // release our change set buffer explicitly
            changeSet.Dispose();
        }