@@ -24,6 +24,9 @@ final DatabaseTracker tracker = DatabaseTracker();
2424class DatabaseTracker {
2525 final Database _db;
2626
27+ /// Whether this [DatabaseTracker] has been disposed.
28+ bool _isDisposed = false ;
29+
2730 /// Creates a new tracker with necessary tables.
2831 DatabaseTracker ()
2932 : _db = sqlite3.open (
@@ -38,24 +41,36 @@ CREATE TABLE IF NOT EXISTS open_connections(
3841 ''' );
3942 }
4043
41- /// Tracks the [openedDb] . The [path] argument can be used to track the path
42- /// of that database, if it's bound to a file.
44+ /// Tracks the [openedDb] . The [path] argument can be used to track
45+ /// the path of that database, if it's bound to a file.
46+ ///
47+ /// Throws a [StateError] if this tracker has already been disposed.
4348 void markOpened (String path, Database openedDb) {
49+ _checkIfDisposed ();
50+
4451 final stmt = _db.prepare ('INSERT INTO open_connections VALUES (?, ?)' );
4552 stmt.execute ([openedDb.handle.address, path]);
4653 stmt.dispose ();
4754 }
4855
4956 /// Marks the database [db] as closed.
57+ ///
58+ /// Throws a [StateError] if this tracker has already been disposed.
5059 void markClosed (Database db) {
60+ _checkIfDisposed ();
61+
5162 final ptr = db.handle.address;
5263 _db.execute ('DELETE FROM open_connections WHERE database_pointer = $ptr ' );
5364 }
5465
55- /// Closes tracked database connections.
66+ /// Closes all tracked database connections that are still open.
67+ ///
68+ /// This operation is wrapped in a transaction (`BEGIN` ... `COMMIT` ).
69+ /// Throws a [StateError] if this tracker has already been disposed.
5670 void closeExisting () {
57- _db. execute ( 'BEGIN;' );
71+ _checkIfDisposed ( );
5872
73+ _db.execute ('BEGIN;' );
5974 try {
6075 final results =
6176 _db.select ('SELECT database_pointer FROM open_connections' );
@@ -70,4 +85,33 @@ CREATE TABLE IF NOT EXISTS open_connections(
7085 _db.execute ('COMMIT;' );
7186 }
7287 }
88+
89+ /// Releases all open database handles managed by this tracker and
90+ /// closes the internal in-memory database.
91+ ///
92+ /// After calling this method, this instance should no longer be used.
93+ /// Any further calls to public methods will throw a [StateError] .
94+ void dispose () {
95+ if (_isDisposed) {
96+ return ;
97+ }
98+
99+ // Safely close any tracked connections
100+ closeExisting ();
101+
102+ // Dispose of the in-memory tracker database
103+ _db.dispose ();
104+
105+ // Mark this tracker as disposed
106+ _isDisposed = true ;
107+ }
108+
109+ /// Checks if this tracker has been disposed and throws a [StateError] if so.
110+ void _checkIfDisposed () {
111+ if (_isDisposed) {
112+ throw StateError (
113+ 'DatabaseTracker has already been disposed and can no longer be used.' ,
114+ );
115+ }
116+ }
73117}
0 commit comments