0

I have the following code

  Future<InitData> getInitialData() async {
    print('OPENING');
    await open();
    print('DB = $_db ${_db.isOpen}');
    final rawDayActionTypes = await _db.query(...);

Where function open is the following

  Future<Database> open() async {
    if (_db != null && _db.isOpen) {
      return _db;
    }

    final dbPath = await sql.getDatabasesPath();
    final myDBPath = path.join(dbPath, db_name);
    _db = await sql.openDatabase(myDBPath, onCreate: _onCreateDB, version: 1);
    return _db;
  }

But after a hot reload, I get often the following error:

I/flutter (10806): DB = 1161 <db_name>.db true
E/flutter (10806): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: DatabaseException(error database_closed)
E/flutter (10806): #0      SqfliteDatabaseMixin.checkNotClosed 
package:sqflite_common/src/database_mixin.dart:282
E/flutter (10806): #1      SqfliteDatabaseExecutorMixin._rawQuery 
package:sqflite_common/src/database_mixin.dart:125
E/flutter (10806): #2      SqfliteDatabaseExecutorMixin.query 
package:sqflite_common/src/database_mixin.dart:110
E/flutter (10806): #3      DBService.getInitialData 
package:productive_diary/db/db_service.dart:56
E/flutter (10806): <asynchronous suspension>
E/flutter (10806): #4      _InitDBDataState._fetchData 
package:productive_diary/initScreen.dart:53
E/flutter (10806): #5      _InitDBDataState.didChangeDependencies 

As you can see the DB was open (DB = 1161 <db_name>.db true)
on the line before executing the query(await _db.query(...);)

If you need to know what _InitDBDataState is doing in order to understand the context of the error,
you can check this related question

Draxent
  • 500
  • 1
  • 6
  • 14

1 Answers1

1

sqflite supports hot-restart by finding the opened database if any (i.e. the dart side restarts but the native database is still open). hot-reload should not cause any issue.

The only thing I could think off is if you have a _db.close() call somewhere. In a typical one database scenario you should simply open the database on start and never close it.

If you are in this scenario, can ensure that close() is never called? (and try to comment this code)

alextk
  • 5,713
  • 21
  • 34
  • Yes, you are right, it solved my issue. But I am confused. Shouldn't the database be opened and closed for every bunch of operations, as you do it when you read and write a file? Shouldn't close and open the DB at least when my application get detached and resumed again? – Draxent May 05 '20 at 13:06
  • 1
    Opening the database is an expensive operation and you are likely going to deal with database_close issues unless you wrap all your calls to make sure the database is open. Personally I would keep it open if you constantly access the database like most people do on Android and iOS. I cannot tell how much RAM is takes though to keep it open. – alextk May 05 '20 at 16:58
  • So when someone should call db.close()? – Draxent May 08 '20 at 13:36
  • One scenario: you have one database to cache some web services data for the current user. You could decide to have one database per logged in user and when the user changes you could close the current database to open a new one. – alextk May 08 '20 at 14:05