openDatabase method
Opens the database identified by localId using passphrase to derive
its encryption key and room tag.
The key is written to the KeyStore after a successful open, so the database can later be reopened via reopenDatabase without the passphrase.
The derived key is validated against local storage before this method returns, whether or not an Identity is configured: with the disk-backed engine, a passphrase that does not decrypt existing local data throws WrongPassphraseException, the data on disk is left untouched, and no key is stored, so retrying with the right passphrase succeeds. The in-memory engine has nothing to validate against and accepts any passphrase.
Implementation
Future<Database> openDatabase(
String localId, {
required String passphrase,
}) async {
if (_databases.containsKey(localId)) return _databases[localId]!;
await resumePendingRotation(localId);
if (_config.passphrasePolicy.strictness == PassphraseStrictness.reject &&
!_validateMnemonic(passphrase)) {
throw const WeakPassphraseException();
}
final entryKey = '${_config.appId}/$localId';
final key = await _deriveKey(passphrase, _config.salt);
final cipher = _cipherFactory(key);
final db = await _finishOpen(localId, entryKey, key, cipher);
// Only a key that opened the database is worth keeping: storing it before
// the open would make every later [reopenDatabase] repeat a wrong
// passphrase.
await _keyStore.setKey(entryKey, key);
return db;
}