simolus3 / drift

Drift is an easy to use, reactive, typesafe persistence library for Dart & Flutter.
https://drift.simonbinder.eu/
MIT License
2.66k stars 372 forks source link

How to switch links from different sqlite files #2514

Open JasonYHZ opened 1 year ago

JasonYHZ commented 1 year ago

In app, I need to dynamically create corresponding sqlite files according to the user's id. When one of my users logs out, and then another user logs in, how do I switch the corresponding sqlite files of other users?

Now I have recreated an object after using the close () method

However, the following error prompt appears on the recreated object

[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Tried to send Request (id = 18): StatementMethod.deleteOrUpdate: UPDATE chatRecord SET isRead = ?1 WHERE channelId = ?2 AND senderId = ?3 with [1, 16ecf86d7133400116ea8f118832c002, 1651968312272437249] over isolate channel, but the connection was closed!
#0      DriftCommunication._send (package:drift/src/remote/communication.dart:128:7)
#1      DriftCommunication.request (package:drift/src/remote/communication.dart:115:5)
#2      _BaseExecutor._runRequest (package:drift/src/remote/client_impl.dart:97:28)
#3      _BaseExecutor.runUpdate (package:drift/src/remote/client_impl.dart:119:12)
#4      LazyDatabase.runUpdate (package:drift/src/utils/lazy_database.dart:88:17)
#5      DatabaseConnection.runUpdate (package:drift/src/runtime/api/connection.dart:112:16)
#6      LazyDatabase.runUpdate (package:drift/src/utils/lazy_database.dart:88:17)
#7      DatabaseConnectionUser.customUpdate.<anonymous closure> (package:drift/src/runtime/api<…>

My logic for creating the database is like this.


class ChatDatabaseService extends GetxService {
  static ChatDatabaseService get to => Get.find();

  late ChatDatabase chatDatabase;

  void connect(String uid) {
    chatDatabase = ChatDatabase(uid);
  }
  void close() {
    chatDatabase.close();
  }
}
simolus3 commented 1 year ago

Closing the old database and then opening the new one under a different path sounds reasonable.

This sounds similar to #2515: There appears to be a place where you're running an update asynchronously (someplace where you set isRead: true) after you've closed the database. The only solution at the moment is to not do that, but since it has come up multiple times, perhaps we should improve the APIs here. Do you have a way to not use the old database after closing it (this may be hard to implement when some tasks are accessing the database asynchronously, or are not properly notified that there is a new database instance).