@@ -24,6 +24,12 @@ final DatabaseTracker tracker = DatabaseTracker();
2424class DatabaseTracker {
2525 final Database _db;
2626
27+ /// Whether this [DatabaseTracker] has been disposed.
28+ bool _isDisposed = false ;
29+
30+ /// Public getter to check if this tracker has been disposed.
31+ bool get isDisposed => _isDisposed;
32+
2733 /// Creates a new tracker with necessary tables.
2834 DatabaseTracker ()
2935 : _db = sqlite3.open (
@@ -38,27 +44,38 @@ CREATE TABLE IF NOT EXISTS open_connections(
3844 ''' );
3945 }
4046
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.
47+ /// Tracks the [openedDb] . The [path] argument can be used to track
48+ /// the path of that database, if it's bound to a file.
49+ ///
50+ /// Throws a [StateError] if this tracker has already been disposed.
4351 void markOpened (String path, Database openedDb) {
52+ _checkIfDisposed ();
53+
4454 final stmt = _db.prepare ('INSERT INTO open_connections VALUES (?, ?)' );
4555 stmt.execute ([openedDb.handle.address, path]);
4656 stmt.dispose ();
4757 }
4858
4959 /// Marks the database [db] as closed.
60+ ///
61+ /// Throws a [StateError] if this tracker has already been disposed.
5062 void markClosed (Database db) {
63+ _checkIfDisposed ();
64+
5165 final ptr = db.handle.address;
5266 _db.execute ('DELETE FROM open_connections WHERE database_pointer = $ptr ' );
5367 }
5468
55- /// Closes tracked database connections.
69+ /// Closes all tracked database connections that are still open.
70+ ///
71+ /// This operation is wrapped in a transaction (`BEGIN` ... `COMMIT` ).
72+ /// Throws a [StateError] if this tracker has already been disposed.
5673 void closeExisting () {
57- _db. execute ( 'BEGIN;' );
74+ _checkIfDisposed ( );
5875
76+ _db.execute ('BEGIN;' );
5977 try {
60- final results =
61- _db.select ('SELECT database_pointer FROM open_connections' );
78+ final results = _db.select ('SELECT database_pointer FROM open_connections' );
6279
6380 for (final row in results) {
6481 final ptr = Pointer .fromAddress (row.columnAt (0 ) as int );
@@ -70,4 +87,33 @@ CREATE TABLE IF NOT EXISTS open_connections(
7087 _db.execute ('COMMIT;' );
7188 }
7289 }
90+
91+ /// Releases all open database handles managed by this tracker and
92+ /// closes the internal in-memory database.
93+ ///
94+ /// After calling this method, this instance should no longer be used.
95+ /// Any further calls to public methods will throw a [StateError] .
96+ void dispose () {
97+ if (_isDisposed) {
98+ return ;
99+ }
100+
101+ // Safely close any tracked connections
102+ closeExisting ();
103+
104+ // Dispose of the in-memory tracker database
105+ _db.dispose ();
106+
107+ // Mark this tracker as disposed
108+ _isDisposed = true ;
109+ }
110+
111+ /// Checks if this tracker has been disposed and throws a [StateError] if so.
112+ void _checkIfDisposed () {
113+ if (_isDisposed) {
114+ throw StateError (
115+ 'DatabaseTracker has already been disposed and can no longer be used.' ,
116+ );
117+ }
118+ }
73119}
0 commit comments