public void CallbackClientToClient() { var sourceMaster = CreateConnectionNewSource(new SocketConnectionBuilder(Address, 1202, Backlog, HeartBeatTimeOut), null); var sourceClient = CreateConnection(new SocketConnectionBuilder(Address, 1202, Backlog, HeartBeatTimeOut), sourceMaster); var destinationMaster = CreateConnectionNewSource(new SocketConnectionBuilder(Address, 1203, Backlog, HeartBeatTimeOut), null); var destinationClient = CreateConnection(new SocketConnectionBuilder(Address, 1203, Backlog, HeartBeatTimeOut), destinationMaster); sourceMaster.Open(); sourceClient.Open(); destinationMaster.Open(); destinationClient.Open(); // add data to source const string sqlMaster = "create table tb_config (name varchar(20), value INTEGER)"; using (var command = new SQLiteServerCommand(sqlMaster, sourceClient)) { command.ExecuteNonQuery(); } for (var i = 0; i < 100; ++i) { var long1 = RandomNumber <long>(); var sql = $"insert into tb_config(name, value) VALUES ('a', {long1})"; using (var command = new SQLiteServerCommand(sql, sourceClient)) { command.ExecuteNonQuery(); } } var called = 0; var callback = new SQLiteServerBackupCallback( (sc, sn, dc, dn, page, remainingPages, totalPages, retry) => { Assert.AreEqual(page, 1); Assert.AreEqual(remainingPages, 1); Assert.AreEqual(totalPages, 2); Assert.AreEqual(retry, false); ++called; return(true); }); // backup // page size is 1 - (or 1024) // we added 100 long = 4 bytes // and we added '100' 'a' = 2 bytes // 400 + 200 = 600 = one page sourceClient.BackupDatabase(destinationClient, "main", "main", 1, callback, 0); // check that this was called exactly once // that way we know the other asserts are checked. Assert.AreEqual(1, called); sourceMaster.Close(); destinationMaster.Close(); sourceClient.Close(); destinationClient.Close(); }
/// <summary> /// Backup the database /// </summary> /// <param name="destination"></param> /// <param name="destinationName"></param> /// <param name="sourceName"></param> /// <param name="pages"></param> /// <param name="callback"></param> /// <param name="retryMilliseconds"></param> public void BackupDatabase( SQLiteServerConnection destination, string destinationName, string sourceName, int pages, SQLiteServerBackupCallback callback, int retryMilliseconds) { // check not disposed ThrowIfAny(); // check destination is valid. if (destination == null) { throw new ArgumentNullException(nameof(destination)); } if (destination.State != ConnectionState.Open) { throw new InvalidOperationException("Destination database is not open."); } // validate the names if (destinationName == null) { throw new ArgumentNullException(nameof(destinationName)); } if (sourceName == null) { throw new ArgumentNullException(nameof(sourceName)); } // convert the callback to sqlite callback // but only if the caller gave us a callback. var callback2 = callback == null ? null : new SQLiteBackupCallback( (source2, sourceName2, destination2, destinationName2, pages2, remainingPages, totalPages, retry) => callback(this, sourceName2, destination, destinationName2, pages2, remainingPages, totalPages, retry)); try { // get the sqlite connections. Task.Run(async() => { var sourceConnection = await _worker.LockConnectionAsync().ConfigureAwait(false); var destinationConnection = await destination._worker.LockConnectionAsync().ConfigureAwait(false); // Call the SQlite connection. sourceConnection.BackupDatabase(destinationConnection, destinationName, sourceName, pages, callback2, retryMilliseconds); }).Wait(); } finally { Task.Run(async() => { await _worker.UnLockConnectionAsync().ConfigureAwait(false); await destination._worker.UnLockConnectionAsync().ConfigureAwait(false); }).Wait(); } }