Skip to content

Commit a8f2787

Browse files
committed
Automatically dispose a database backup if either the src or dest dbs is disposed.
1 parent b4263bb commit a8f2787

3 files changed

Lines changed: 20 additions & 6 deletions

File tree

SQLitePCL.pretty.tests/ImplementationTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public void TestDispose()
3838
db.Execute("INSERT INTO foo (x) VALUES (?);", i);
3939
}
4040

41+
IDatabaseBackup notDisposedBackup;
42+
4143
using (var db2 = SQLite3.Open(":memory:"))
4244
{
4345
var backup = db.BackupInit("main", db2, "main");
@@ -46,7 +48,15 @@ public void TestDispose()
4648
Assert.Throws<ObjectDisposedException>(() => { var x = backup.PageCount; });
4749
Assert.Throws<ObjectDisposedException>(() => { var x = backup.RemainingPages; });
4850
Assert.Throws<ObjectDisposedException>(() => { backup.Step(1); });
51+
52+
notDisposedBackup = db.BackupInit("main", db2, "main");
4953
}
54+
55+
// Ensure diposing the database connection automatically disposes the backup as well.
56+
Assert.Throws<ObjectDisposedException>(() => { var x = notDisposedBackup.PageCount; });
57+
58+
// Test double disposing doesn't result in exceptions.
59+
notDisposedBackup.Dispose();
5060
}
5161
}
5262

SQLitePCL.pretty/DatabaseConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ public IDatabaseBackup BackupInit(string dbName, SQLiteDatabaseConnection destCo
960960
if (disposed) { throw new ObjectDisposedException(this.GetType().FullName); }
961961

962962
sqlite3_backup backup = raw.sqlite3_backup_init(destConn.db, destDbName, db, dbName);
963-
var result = new DatabaseBackupImpl(backup, this);
963+
var result = new DatabaseBackupImpl(backup, this, destConn);
964964
return result;
965965
}
966966

SQLitePCL.pretty/Implementation.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ namespace SQLitePCL.pretty
2626
internal sealed class DatabaseBackupImpl : IDatabaseBackup
2727
{
2828
private readonly sqlite3_backup backup;
29-
private readonly SQLiteDatabaseConnection db;
29+
private readonly SQLiteDatabaseConnection srcDb;
30+
private readonly SQLiteDatabaseConnection destDb;
3031
private readonly EventHandler dbDisposing;
3132

3233
private bool disposed = false;
3334

34-
internal DatabaseBackupImpl(sqlite3_backup backup, SQLiteDatabaseConnection db)
35+
internal DatabaseBackupImpl(sqlite3_backup backup, SQLiteDatabaseConnection srcDb, SQLiteDatabaseConnection destDb)
3536
{
3637
this.backup = backup;
37-
this.db = db;
38+
this.srcDb = srcDb;
39+
this.destDb = destDb;
3840

3941
this.dbDisposing = (o, e) => Dispose();
40-
this.db.Disposing += dbDisposing;
42+
this.srcDb.Disposing += dbDisposing;
43+
this.destDb.Disposing += dbDisposing;
4144
}
4245

4346
public int PageCount
@@ -68,7 +71,8 @@ public void Dispose()
6871
// FIXME: What to do about errors?
6972
raw.sqlite3_backup_finish(backup);
7073

71-
db.Disposing -= dbDisposing;
74+
srcDb.Disposing -= dbDisposing;
75+
destDb.Disposing -= dbDisposing;
7276
}
7377

7478
public bool Step(int nPages)

0 commit comments

Comments
 (0)