Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deleting database with sqlflite in flutter doesn't seem to be working

For my app I'm loading in a pre-populated database with some starter/default data for the user following this tutorial: https://github.com/tekartik/sqflite/blob/master/doc/opening_asset_db.md While debugging I'm going to be adding/deleting a bunch of test data and don't want to have to manually reset things every time I want to reload the app, so I have it load a fresh copy from the database every time.

For some reason however it isn't loading a new copy from the asset but rather still opening the existing modified database. I've checked the asset file and it's not been modified and the block that opens the existing database on the machine without deleting the previous version is not reached.

I'm not getting any errors in the console either.

Here's the code for initializing the database:

static Database _db;

  Future<Database> get db async {
    if(_db != null)
      return _db;
    _db = await initDb();
    return _db;
  }

  bool get isInDebugMode {
    bool inDebugMode = false;
    assert(inDebugMode = true);
    return inDebugMode;
  }

  //load database from existing db or copy pre-loaded db from assets
  initDb() async {
    //if in debug mode always load from asset file
    //done to reload from asset when default values added to database asset
    //and get rid of testing data
    //since it would be annoying to have to delete the file on the emulator every time

    debugPrint("initializing the db connection");
    var databasesPath = await getDatabasesPath();
    var path = join(databasesPath, "myDatabase.db");

    if(isInDebugMode){
      // delete existing if any
      await deleteDatabase(path);

      // Copy from asset
      ByteData data = await rootBundle.load(join("assets", "assetDB.db"));
      List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
      await new File(path).writeAsBytes(bytes);

      // open the database
      var db = await openDatabase(path, readOnly: false);
      return db;

    } else {
      // try opening (will work if it exists)
      Database db;
      try {
        db = await openDatabase(path, readOnly: false);
      } catch (e) {
        print("Error $e");
      }

      if (db == null) {
        // Should happen only the first time you launch your application
        print("Creating new copy from asset");

        // Copy from asset
        ByteData data = await rootBundle.load(join("assets", "assetDB.db"));
        List<int> bytes =
        data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
        await new File(path).writeAsBytes(bytes);

        //debugPrint(bytes.length.toString());

        // open the database
        db = await openDatabase(path, readOnly: true);
      } else {
        print("Opening existing database");
      }

      return db;
    }

  }

I should mention I'm not doing a hot reload when I load these changes and the block that initializes the new database from the asset for when in debug mode is reached.

Thanks for your help!

like image 866
A. Lynch Avatar asked Jan 24 '19 16:01

A. Lynch


People also ask

How do I delete data from SQLite in flutter?

You can use in this manner: deleted = await db. delete(Place. tableName(), where: "name = ?", whereArgs: [name]);

Can I delete db SQLite?

SQLite is an embedded database engine, so in order to drop a database you have to delete the file from the machine. This action will make the database no longer accessible.

How do I check SQLite database in flutter?

Connect to the SQLite DB this tool will be there inside the platform-tools folder in your android SDK path. SDK path will be shown in android studio > sdk manager. Now navigate inside the sdk location and then inside the platform-tools folder.

Where is SQLite database stored in flutter?

By default, the database file is saved in a folder data/data/your package name/databases on an Android device, while On iOS and macOS, it is the Documents directory. If you want to check the file directory, the below statement will show the path: String path = await getDatabasesPath();


1 Answers

Hotreload and plugins don't always play well together unless you take extra cares. In your case, you try to delete a database that might still be opened. So you should try to close it before deleting it. One solution is to hold a global reference to the database and closing it before calling deleteDatabase

like image 135
alextk Avatar answered Oct 02 '22 15:10

alextk