diff --git a/doc/get-started.md b/doc/get-started.md index 5b2d5f69..fa3d1267 100644 --- a/doc/get-started.md +++ b/doc/get-started.md @@ -16,11 +16,30 @@ In your `pubspec.yaml` file add the following dependencies: ## Step 2: Create the client ```dart +import 'package:sqflite_common_ffi/sqflite_ffi.dart'; +import 'package:matrix/matrix.dart'; + final client = Client( - '', - databaseBuilder: (client) => MatrixSdkDatabase( + '', + database: await MatrixSdkDatabase.init( '', - database: await openDatabase(''), + database: await databaseFactoryFfi.openDatabase(':memory:'), + sqfliteFactory: databaseFactoryFfi, + ), +); +``` + +### Alternative: Create a persistent database with SQFlite: + +```dart +import 'package:sqflite/sqflite.dart'; +import 'package:matrix/matrix.dart'; + +final client = Client( + '', + database: await MatrixSdkDatabase.init( + '', + database: await openDatabase('/path/to/database.sqlite'), ), ); ``` diff --git a/example/main.dart b/example/main.dart index f7df0c92..ced49395 100644 --- a/example/main.dart +++ b/example/main.dart @@ -7,18 +7,18 @@ import 'package:sqflite/sqflite.dart' as sqlite; void main() async { WidgetsFlutterBinding.ensureInitialized(); + // Build the database + final dbDirectory = await getApplicationSupportDirectory(); + final client = Client( 'Matrix Example Chat', - databaseBuilder: (_) async { - final dir = await getApplicationSupportDirectory(); - final db = MatrixSdkDatabase( - c.name, - await sqlite.openDatabase(dir.toString() + '/database.sqlite'), - ); - await db.open(); - return db; - }, + database: await MatrixSdkDatabase.init( + c.name, + database: + await sqlite.openDatabase(directory.toString() + '/database.sqlite'), + ), ); + await client.init(); runApp(MatrixExampleChat(client: client)); } diff --git a/lib/encryption/encryption.dart b/lib/encryption/encryption.dart index 176766c2..2e711fcd 100644 --- a/lib/encryption/encryption.dart +++ b/lib/encryption/encryption.dart @@ -246,7 +246,7 @@ class Encryption { // it un-awaited here, nothing happens, which is exactly the result we want client.database // ignore: discarded_futures - ?.updateInboundGroupSessionIndexes( + .updateInboundGroupSessionIndexes( json.encode(inboundGroupSession.indexes), event.room.id, sessionId, @@ -319,8 +319,7 @@ class Encryption { } final content = event.parsedRoomEncryptedContent; final sessionId = content.sessionId; - if (client.database != null && - sessionId != null && + if (sessionId != null && !(keyManager .getInboundGroupSession( event.room.id, @@ -347,7 +346,7 @@ class Encryption { if (updateType != EventUpdateType.history) { event.room.setState(event); } - await client.database?.storeEventUpdate( + await client.database.storeEventUpdate( event.room.id, event, updateType, @@ -429,8 +428,7 @@ class Encryption { // check if we can set our own master key as verified, if it isn't yet final userId = client.userID; final masterKey = client.userDeviceKeys[userId]?.masterKey; - if (client.database != null && - masterKey != null && + if (masterKey != null && userId != null && !masterKey.directVerified && masterKey.hasValidSignatureChain(onlyValidateUserIds: {userId})) { diff --git a/lib/encryption/key_manager.dart b/lib/encryption/key_manager.dart index ade2762d..77fe1679 100644 --- a/lib/encryption/key_manager.dart +++ b/lib/encryption/key_manager.dart @@ -166,7 +166,7 @@ class KeyManager { } final storeFuture = client.database - ?.storeInboundGroupSession( + .storeInboundGroupSession( roomId, sessionId, inboundGroupSession.pickle(userId), @@ -182,7 +182,7 @@ class KeyManager { } if (uploaded) { await client.database - ?.markInboundGroupSessionAsUploaded(roomId, sessionId); + .markInboundGroupSessionAsUploaded(roomId, sessionId); } }); final room = client.getRoomById(roomId); @@ -198,7 +198,7 @@ class KeyManager { room.lastEvent = decrypted; // To persist it in database and trigger UI updates: - await client.database?.transaction(() async { + await client.database.transaction(() async { await client.handleSync( SyncUpdate( nextBatch: '', @@ -222,7 +222,7 @@ class KeyManager { room.onSessionKeyReceived.add(sessionId); } - return storeFuture ?? Future.value(); + return storeFuture; } SessionKey? getInboundGroupSession(String roomId, String sessionId) { @@ -277,7 +277,7 @@ class KeyManager { return sess; // nothing to do } final session = - await client.database?.getInboundGroupSession(roomId, sessionId); + await client.database.getInboundGroupSession(roomId, sessionId); if (session == null) return null; final userID = client.userID; if (userID == null) return null; @@ -455,7 +455,7 @@ class KeyManager { sess.outboundGroupSession!.message_index(); } } - await client.database?.updateInboundGroupSessionAllowedAtIndex( + await client.database.updateInboundGroupSessionAllowedAtIndex( json.encode(inboundSess!.allowedAtIndex), room.id, sess.outboundGroupSession!.session_id(), @@ -479,7 +479,7 @@ class KeyManager { } sess.dispose(); _outboundGroupSessions.remove(roomId); - await client.database?.removeOutboundGroupSession(roomId); + await client.database.removeOutboundGroupSession(roomId); return true; } @@ -490,7 +490,7 @@ class KeyManager { ) async { final userID = client.userID; if (userID == null) return; - await client.database?.storeOutboundGroupSession( + await client.database.storeOutboundGroupSession( roomId, sess.outboundGroupSession!.pickle(userID), json.encode(sess.devices), @@ -621,7 +621,6 @@ class KeyManager { final userID = client.userID; if (_loadedOutboundGroupSessions.contains(roomId) || _outboundGroupSessions.containsKey(roomId) || - database == null || userID == null) { return; // nothing to do } @@ -847,7 +846,7 @@ class KeyManager { }) async { final database = client.database; final userID = client.userID; - if (database == null || userID == null) { + if (userID == null) { return; } diff --git a/lib/encryption/ssss.dart b/lib/encryption/ssss.dart index e95669dd..6e67abbc 100644 --- a/lib/encryption/ssss.dart +++ b/lib/encryption/ssss.dart @@ -68,7 +68,7 @@ class SSSS { // for testing Future clearCache() async { - await client.database?.clearSSSSCache(); + await client.database.clearSSSSCache(); _cache.clear(); } @@ -301,10 +301,6 @@ class SSSS { client.accountData[type]?.content['encrypted'] is Map; Future getCached(String type) async { - if (client.database == null) { - return null; - } - // check if it is still valid final keys = keyIdsFromType(type); if (keys == null) { return null; @@ -323,7 +319,7 @@ class SSSS { if (fromCache != null && isValid(fromCache)) { return fromCache.content; } - final ret = await client.database?.getSSSSCache(type); + final ret = await client.database.getSSSSCache(type); if (ret == null) { return null; } @@ -361,7 +357,7 @@ class SSSS { ); final decrypted = await decryptAes(encryptInfo, key, type); final db = client.database; - if (cacheTypes.contains(type) && db != null) { + if (cacheTypes.contains(type)) { // cache the thing await db.storeSSSSCache(type, keyId, ciphertext, decrypted); onSecretStored.add(keyId); @@ -398,7 +394,7 @@ class SSSS { // store the thing in your account data await client.setAccountData(client.userID!, type, content); final db = client.database; - if (cacheTypes.contains(type) && db != null) { + if (cacheTypes.contains(type)) { // cache the thing await db.storeSSSSCache(type, keyId, encrypted.ciphertext, secret); onSecretStored.add(keyId); @@ -444,7 +440,7 @@ class SSSS { if (ciphertext == null) { throw Exception('Wrong type for ciphertext!'); } - await client.database?.storeSSSSCache(type, keyId, ciphertext, secret); + await client.database.storeSSSSCache(type, keyId, ciphertext, secret); onSecretStored.add(keyId); } } @@ -611,23 +607,21 @@ class SSSS { } Logs().i('[SSSS] Secret for type ${request.type} is ok, storing it'); final db = client.database; - if (db != null) { - final keyId = keyIdFromType(request.type); - if (keyId != null) { - final ciphertext = (client.accountData[request.type]!.content - .tryGetMap('encrypted')) - ?.tryGetMap(keyId) - ?.tryGet('ciphertext'); - if (ciphertext == null) { - Logs().i('[SSSS] Ciphertext is empty or not a String'); - return; - } - await db.storeSSSSCache(request.type, keyId, ciphertext, secret); - if (_cacheCallbacks.containsKey(request.type)) { - _cacheCallbacks[request.type]!(secret); - } - onSecretStored.add(keyId); + final keyId = keyIdFromType(request.type); + if (keyId != null) { + final ciphertext = (client.accountData[request.type]!.content + .tryGetMap('encrypted')) + ?.tryGetMap(keyId) + ?.tryGet('ciphertext'); + if (ciphertext == null) { + Logs().i('[SSSS] Ciphertext is empty or not a String'); + return; } + await db.storeSSSSCache(request.type, keyId, ciphertext, secret); + if (_cacheCallbacks.containsKey(request.type)) { + _cacheCallbacks[request.type]!(secret); + } + onSecretStored.add(keyId); } } } diff --git a/lib/encryption/utils/bootstrap.dart b/lib/encryption/utils/bootstrap.dart index 163921b1..1746f28e 100644 --- a/lib/encryption/utils/bootstrap.dart +++ b/lib/encryption/utils/bootstrap.dart @@ -583,7 +583,7 @@ class Bootstrap { Logs().v( 'And finally set all megolm keys as needing to be uploaded again...', ); - await client.database?.markInboundGroupSessionsAsNeedingUpload(); + await client.database.markInboundGroupSessionsAsNeedingUpload(); Logs().v('And uploading keys...'); await client.encryption?.keyManager.uploadInboundGroupSessions(); } catch (e, s) { diff --git a/lib/fake_matrix_api.dart b/lib/fake_matrix_api.dart index dc2641af..95150547 100644 --- a/lib/fake_matrix_api.dart +++ b/lib/fake_matrix_api.dart @@ -225,7 +225,7 @@ class FakeMatrixApi extends BaseClient { accountData: [sdk.BasicEvent(content: decodeJson(data), type: type)], ); if (_client?.database != null) { - await _client?.database?.transaction(() async { + await _client?.database.transaction(() async { await _client?.handleSync(syncUpdate); }); } else { @@ -255,7 +255,7 @@ class FakeMatrixApi extends BaseClient { ), ); if (_client?.database != null) { - await _client?.database?.transaction(() async { + await _client?.database.transaction(() async { await _client?.handleSync(syncUpdate); }); } else { diff --git a/lib/msc_extensions/extension_timeline_export/timeline_export.dart b/lib/msc_extensions/extension_timeline_export/timeline_export.dart index 2f9cb4d9..47d7751f 100644 --- a/lib/msc_extensions/extension_timeline_export/timeline_export.dart +++ b/lib/msc_extensions/extension_timeline_export/timeline_export.dart @@ -110,9 +110,8 @@ extension TimelineExportExtension on Timeline { } // From the database - final eventsFromStore = await room.client.database - ?.getEventList(room, start: events.length) ?? - []; + final eventsFromStore = + await room.client.database.getEventList(room, start: events.length); if (eventsFromStore.isNotEmpty) { if (until == null || eventsFromStore.last.originServerTs.isBefore(until)) { diff --git a/lib/src/client.dart b/lib/src/client.dart index f63e1817..577c94ef 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -67,11 +67,9 @@ class Client extends MatrixApi { int? get id => _id; - final FutureOr Function(Client)? databaseBuilder; final FutureOr Function(Client)? legacyDatabaseBuilder; - DatabaseApi? _database; - DatabaseApi? get database => _database; + final DatabaseApi database; Encryption? get encryption => _encryption; Encryption? _encryption; @@ -141,7 +139,6 @@ class Client extends MatrixApi { set homeserver(Uri? homeserver) { if (this.homeserver != null && homeserver?.host != this.homeserver?.host) { _wellKnown = null; - unawaited(database?.storeWellKnown(null)); } super.homeserver = homeserver; } @@ -192,7 +189,7 @@ class Client extends MatrixApi { /// Set [enableDehydratedDevices] to enable experimental support for enabling MSC3814 dehydrated devices. Client( this.clientName, { - this.databaseBuilder, + required this.database, this.legacyDatabaseBuilder, Set? verificationMethods, http.Client? httpClient, @@ -295,7 +292,7 @@ class Client extends MatrixApi { /// Throws an Exception if there is no refresh token available or the /// client is not logged in. Future refreshAccessToken() async { - final storedClient = await database?.getClient(clientName); + final storedClient = await database.getClient(clientName); final refreshToken = storedClient?.tryGet('refresh_token'); if (refreshToken == null) { throw Exception('No refresh token available'); @@ -318,7 +315,7 @@ class Client extends MatrixApi { ? null : DateTime.now().add(Duration(milliseconds: expiresInMs)); _accessTokenExpiresAt = tokenExpiresAt; - await database?.updateClient( + await database.updateClient( homeserverUrl, tokenResponse.accessToken, tokenExpiresAt, @@ -596,7 +593,7 @@ class Client extends MatrixApi { // do not reset the well known here, so super call super.homeserver = wellKnown.mHomeserver.baseUrl.stripTrailingSlash(); _wellKnown = wellKnown; - await database?.storeWellKnown(wellKnown); + await database.storeWellKnown(wellKnown); return wellKnown; } @@ -1060,7 +1057,7 @@ class Client extends MatrixApi { Duration timeout = const Duration(seconds: 30), Duration maxCacheAge = const Duration(days: 1), }) async { - final cachedProfile = await database?.getUserProfile(userId); + final cachedProfile = await database.getUserProfile(userId); if (cachedProfile != null && !cachedProfile.outdated && DateTime.now().difference(cachedProfile.updated) < maxCacheAge) { @@ -1085,7 +1082,7 @@ class Client extends MatrixApi { updated: DateTime.now(), ); - await database?.storeUserProfile(userId, newCachedProfile); + await database.storeUserProfile(userId, newCachedProfile); return newCachedProfile; } @@ -1540,7 +1537,7 @@ class Client extends MatrixApi { .uploadContent(file, filename: filename, contentType: contentType); final database = this.database; - if (database != null && file.length <= database.maxFileSize) { + if (file.length <= database.maxFileSize) { await database.storeFile( mxc, file, @@ -1572,16 +1569,13 @@ class Client extends MatrixApi { /// /// This can be useful to migrate a session from one device to a future one. Future exportDump() async { - if (database != null) { - await abortSync(); - await dispose(closeDatabase: false); + await abortSync(); + await dispose(closeDatabase: false); - final export = await database!.exportDump(); + final export = await database.exportDump(); - await clear(); - return export; - } - return null; + await clear(); + return export; } /// imports a dumped session @@ -1595,9 +1589,7 @@ class Client extends MatrixApi { // Client was probably not initialized yet. } - _database ??= await databaseBuilder!.call(this); - - final success = await database!.importDump(export); + final success = await database.importDump(export); if (success) { // closing including DB @@ -1790,13 +1782,7 @@ class Client extends MatrixApi { bool returnNullIfSeen = true, }) async { // Get access token if necessary: - final database = _database ??= await databaseBuilder?.call(this); if (!isLogged()) { - if (database == null) { - throw Exception( - 'Can not execute getEventByPushNotification() without a database', - ); - } final clientInfoMap = await database.getClient(clientName); final token = clientInfoMap?.tryGet('token'); if (token == null) { @@ -1814,7 +1800,7 @@ class Client extends MatrixApi { // Create the room object: final room = getRoomById(roomId) ?? - await database?.getSingleRoom(this, roomId) ?? + await database.getSingleRoom(this, roomId) ?? Room( id: roomId, client: this, @@ -1864,7 +1850,7 @@ class Client extends MatrixApi { ); } matrixEvent ??= await database - ?.getEventById(eventId, room) + .getEventById(eventId, room) .timeout(timeoutForServerRequests); try { @@ -1893,7 +1879,7 @@ class Client extends MatrixApi { return null; } final readMarkerEvent = await database - ?.getEventById(room.fullyRead, room) + .getEventById(room.fullyRead, room) .timeout(timeoutForServerRequests); if (readMarkerEvent != null && readMarkerEvent.originServerTs.isAfter( @@ -1940,7 +1926,7 @@ class Client extends MatrixApi { } if (storeInDatabase) { - await database?.transaction(() async { + await database.transaction(() async { await database.storeEventUpdate( roomId, event, @@ -2020,14 +2006,6 @@ class Client extends MatrixApi { ); } - final databaseBuilder = this.databaseBuilder; - if (databaseBuilder != null) { - _database ??= await runBenchmarked( - 'Build database', - () async => await databaseBuilder(this), - ); - } - _groupCallSessionId = randomAlpha(12); /// while I would like to move these to a onLoginStateChanged stream listener @@ -2036,7 +2014,7 @@ class Client extends MatrixApi { _serverConfigCache.invalidate(); _versionsCache.invalidate(); - final account = await this.database?.getClient(clientName); + final account = await database.getClient(clientName); newRefreshToken ??= account?.tryGet('refresh_token'); // can have discovery_information so make sure it also has the proper // account creds @@ -2081,7 +2059,7 @@ class Client extends MatrixApi { if (onLoginStateChanged.value == LoginState.softLoggedOut) { if (newRefreshToken != null && accessToken != null && userID != null) { // Store the new tokens: - await _database?.updateClient( + await database.updateClient( homeserver.toString(), accessToken, accessTokenExpiresAt, @@ -2133,58 +2111,56 @@ class Client extends MatrixApi { onInitStateChanged?.call(InitState.settingUpEncryption); await encryption?.init(olmAccount); - final database = this.database; - if (database != null) { - if (id != null) { - await database.updateClient( - homeserver.toString(), - accessToken, - accessTokenExpiresAt, - newRefreshToken, - userID, - _deviceID, - _deviceName, - prevBatch, - encryption?.pickledOlmAccount, - ); - } else { - _id = await database.insertClient( - clientName, - homeserver.toString(), - accessToken, - accessTokenExpiresAt, - newRefreshToken, - userID, - _deviceID, - _deviceName, - prevBatch, - encryption?.pickledOlmAccount, - ); - } - userDeviceKeysLoading = database - .getUserDeviceKeys(this) - .then((keys) => _userDeviceKeys = keys); - roomsLoading = database.getRoomList(this).then((rooms) { - _rooms = rooms; - _sortRooms(); - }); - _accountDataLoading = database.getAccountData().then((data) { - _accountData = data; - _updatePushrules(); - }); - _discoveryDataLoading = database.getWellKnown().then((data) { - _wellKnown = data; - }); - // ignore: deprecated_member_use_from_same_package - presences.clear(); - if (waitUntilLoadCompletedLoaded) { - onInitStateChanged?.call(InitState.loadingData); - await userDeviceKeysLoading; - await roomsLoading; - await _accountDataLoading; - await _discoveryDataLoading; - } + if (id != null) { + await database.updateClient( + homeserver.toString(), + accessToken, + accessTokenExpiresAt, + newRefreshToken, + userID, + _deviceID, + _deviceName, + prevBatch, + encryption?.pickledOlmAccount, + ); + } else { + _id = await database.insertClient( + clientName, + homeserver.toString(), + accessToken, + accessTokenExpiresAt, + newRefreshToken, + userID, + _deviceID, + _deviceName, + prevBatch, + encryption?.pickledOlmAccount, + ); } + userDeviceKeysLoading = database + .getUserDeviceKeys(this) + .then((keys) => _userDeviceKeys = keys); + roomsLoading = database.getRoomList(this).then((rooms) { + _rooms = rooms; + _sortRooms(); + }); + _accountDataLoading = database.getAccountData().then((data) { + _accountData = data; + _updatePushrules(); + }); + _discoveryDataLoading = database.getWellKnown().then((data) { + _wellKnown = data; + }); + // ignore: deprecated_member_use_from_same_package + presences.clear(); + if (waitUntilLoadCompletedLoaded) { + onInitStateChanged?.call(InitState.loadingData); + await userDeviceKeysLoading; + await roomsLoading; + await _accountDataLoading; + await _discoveryDataLoading; + } + _initLock = false; onLoginStateChanged.add(LoginState.loggedIn); Logs().i( @@ -2238,15 +2214,15 @@ class Client extends MatrixApi { } try { await abortSync(); - await database?.clear(); + await database.clear(); await legacyDatabase?.clear(); _backgroundSync = true; } catch (e, s) { Logs().e('Unable to clear database', e, s); } finally { - await database?.delete(); + await database.delete(); await legacyDatabase?.delete(); - _database = null; + await dispose(); } _id = accessToken = _syncFilterId = @@ -2303,7 +2279,7 @@ class Client extends MatrixApi { if (syncFilterId == null && userID != null) { final syncFilterId = _syncFilterId = await defineFilter(userID, syncFilter); - await database?.storeSyncFilterId(syncFilterId); + await database.storeSyncFilterId(syncFilterId); } return; } @@ -2405,29 +2381,25 @@ class Client extends MatrixApi { } final database = this.database; - if (database != null) { - await userDeviceKeysLoading; - await roomsLoading; - await _accountDataLoading; - _currentTransaction = database.transaction(() async { - await _handleSync(syncResp, direction: Direction.f); - if (prevBatch != syncResp.nextBatch) { - await database.storePrevBatch(syncResp.nextBatch); - } - }); - await runBenchmarked( - 'Process sync', - () async => await _currentTransaction, - syncResp.itemCount, - ); - } else { + await userDeviceKeysLoading; + await roomsLoading; + await _accountDataLoading; + _currentTransaction = database.transaction(() async { await _handleSync(syncResp, direction: Direction.f); - } + if (prevBatch != syncResp.nextBatch) { + await database.storePrevBatch(syncResp.nextBatch); + } + }); + await runBenchmarked( + 'Process sync', + () async => await _currentTransaction, + syncResp.itemCount, + ); if (_disposed || _aborted) return; _prevBatch = syncResp.nextBatch; onSyncStatus.add(SyncStatusUpdate(SyncStatus.cleaningUp)); // ignore: unawaited_futures - database?.deleteOldFiles( + database.deleteOldFiles( DateTime.now().subtract(Duration(days: 30)).millisecondsSinceEpoch, ); await updateUserDeviceKeys(); @@ -2523,10 +2495,10 @@ class Client extends MatrixApi { // ignore: deprecated_member_use_from_same_package onPresence.add(newPresence); onPresenceChanged.add(cachedPresence); - await database?.storePresence(newPresence.senderId, cachedPresence); + await database.storePresence(newPresence.senderId, cachedPresence); } for (final newAccountData in sync.accountData ?? []) { - await database?.storeAccountData( + await database.storeAccountData( newAccountData.type, newAccountData.content, ); @@ -2559,7 +2531,7 @@ class Client extends MatrixApi { final userKeys = _userDeviceKeys[userId]; if (userKeys != null) { userKeys.outdated = true; - await database?.storeUserDeviceKeysInfo(userId, true); + await database.storeUserDeviceKeysInfo(userId, true); } } for (final userId in deviceLists.left ?? []) { @@ -2663,7 +2635,7 @@ class Client extends MatrixApi { // removed from the database! if (syncRoomUpdate is JoinedRoomUpdate && syncRoomUpdate.timeline?.limited == true) { - await database?.deleteTimelineForRoom(id); + await database.deleteTimelineForRoom(id); } final room = await _updateRoomsByRoomUpdate(id, syncRoomUpdate); @@ -2722,7 +2694,7 @@ class Client extends MatrixApi { final accountData = syncRoomUpdate.accountData; if (accountData != null && accountData.isNotEmpty) { for (final event in accountData) { - await database?.storeRoomAccountData(room.id, event); + await database.storeRoomAccountData(room.id, event); room.roomAccountData[event.type] = event; } } @@ -2761,7 +2733,7 @@ class Client extends MatrixApi { await _handleRoomEvents(room, state, EventUpdateType.inviteState); } } - await database?.storeRoomUpdate(id, syncRoomUpdate, room.lastEvent, this); + await database.storeRoomUpdate(id, syncRoomUpdate, room.lastEvent, this); } } @@ -2790,7 +2762,7 @@ class Client extends MatrixApi { type: LatestReceiptState.eventType, content: receiptStateContent.toJson(), ); - await database?.storeRoomAccountData(room.id, event); + await database.storeRoomAccountData(room.id, event); room.roomAccountData[event.type] = event; } } @@ -2844,25 +2816,24 @@ class Client extends MatrixApi { // We do not re-request the profile here as this would lead to // an unknown amount of network requests as we never know how many // member change events can come down in a single sync update. - await database?.markUserProfileAsOutdated(userId); + await database.markUserProfileAsOutdated(userId); onUserProfileUpdate.add(userId); } } if (event.type == EventTypes.Message && !room.isDirectChat && - database != null && event is MatrixEvent && room.getState(EventTypes.RoomMember, event.senderId) == null) { // In order to correctly render room list previews we need to fetch the member from the database - final user = await database?.getUser(event.senderId, room); + final user = await database.getUser(event.senderId, room); if (user != null) { room.setState(user); } } await _updateRoomsByEventUpdate(room, event, type); if (store) { - await database?.storeEventUpdate(room.id, event, type, this); + await database.storeEventUpdate(room.id, event, type, this); } if (event is MatrixEvent && encryptionEnabled) { await encryption?.handleEventUpdate( @@ -3080,7 +3051,7 @@ class Client extends MatrixApi { (event.redacts ?? event.content.tryGet('redacts')) && event.type == EventTypes.Redaction && room.lastEvent?.relationshipType == RelationshipTypes.edit) { - final originalEvent = await database?.getEventById( + final originalEvent = await database.getEventById( relationshipEventId, room, ) ?? @@ -3216,7 +3187,7 @@ class Client extends MatrixApi { Future updateUserDeviceKeys({Set? additionalUsers}) async { try { final database = this.database; - if (!isLogged() || database == null) return; + if (!isLogged()) return; final dbActions = Function()>[]; final trackedUserIds = await _getUserIdsInEncryptedRooms(); if (!isLogged()) return; @@ -3464,7 +3435,7 @@ class Client extends MatrixApi { /// proccessed all the way. Future processToDeviceQueue() async { final database = this.database; - if (database == null || !_toDeviceQueueNeedsProcessing) { + if (!_toDeviceQueueNeedsProcessing) { return; } final entries = await database.getToDeviceEventQueue(); @@ -3518,14 +3489,12 @@ class Client extends MatrixApi { s, ); final database = this.database; - if (database != null) { - _toDeviceQueueNeedsProcessing = true; - await database.insertIntoToDeviceQueue( - eventType, - txnId, - json.encode(messages), - ); - } + _toDeviceQueueNeedsProcessing = true; + await database.insertIntoToDeviceQueue( + eventType, + txnId, + json.encode(messages), + ); rethrow; } } @@ -3762,7 +3731,7 @@ class Client extends MatrixApi { await abortSync(); _prevBatch = null; rooms.clear(); - await database?.clearCache(); + await database.clearCache(); encryption?.keyManager.clearOutboundGroupSessions(); _eventsPendingDecryption.clear(); onCacheCleared.add(true); @@ -3824,7 +3793,7 @@ class Client extends MatrixApi { return cachedPresence; } - final dbPresence = await database?.getPresence(userId); + final dbPresence = await database.getPresence(userId); // ignore: deprecated_member_use_from_same_package if (dbPresence != null) return presences[userId] = dbPresence; @@ -3833,12 +3802,12 @@ class Client extends MatrixApi { try { final result = await getPresence(userId); final presence = CachedPresence.fromPresenceResponse(result, userId); - await database?.storePresence(userId, presence); + await database.storePresence(userId, presence); // ignore: deprecated_member_use_from_same_package return presences[userId] = presence; } catch (e) { final presence = CachedPresence.neverSeen(userId); - await database?.storePresence(userId, presence); + await database.storePresence(userId, presence); // ignore: deprecated_member_use_from_same_package return presences[userId] = presence; } @@ -3873,10 +3842,8 @@ class Client extends MatrixApi { _encryption = null; try { if (closeDatabase) { - final database = _database; - _database = null; await database - ?.close() + .close() .catchError((e, s) => Logs().w('Failed to close database: ', e, s)); } } catch (error, stacktrace) { @@ -3894,7 +3861,7 @@ class Client extends MatrixApi { final migrateClient = await legacyDatabase?.getClient(clientName); final database = this.database; - if (migrateClient == null || legacyDatabase == null || database == null) { + if (migrateClient == null || legacyDatabase == null) { await legacyDatabase?.close(); _initLock = false; return; diff --git a/lib/src/database/matrix_sdk_database.dart b/lib/src/database/matrix_sdk_database.dart index 61970bf1..942418b8 100644 --- a/lib/src/database/matrix_sdk_database.dart +++ b/lib/src/database/matrix_sdk_database.dart @@ -176,23 +176,38 @@ class MatrixSdkDatabase extends DatabaseApi with DatabaseFileStorage { /// like delete. Set it if you want to use sqlite FFI. final DatabaseFactory? sqfliteFactory; - MatrixSdkDatabase( + static Future init( + String name, { + Database? database, + dynamic idbFactory, + DatabaseFactory? sqfliteFactory, + int maxFileSize = 0, + Uri? fileStorageLocation, + Duration? deleteFilesAfterDuration, + }) async { + final matrixSdkDatabase = MatrixSdkDatabase._( + name, + database: database, + idbFactory: idbFactory, + sqfliteFactory: sqfliteFactory, + maxFileSize: maxFileSize, + fileStorageLocation: fileStorageLocation, + deleteFilesAfterDuration: deleteFilesAfterDuration, + ); + await matrixSdkDatabase.open(); + return matrixSdkDatabase; + } + + MatrixSdkDatabase._( this.name, { this.database, this.idbFactory, this.sqfliteFactory, this.maxFileSize = 0, - // TODO : remove deprecated member migration on next major release - @Deprecated( - 'Breaks support for web standalone. Use [fileStorageLocation] instead.', - ) - dynamic fileStoragePath, Uri? fileStorageLocation, Duration? deleteFilesAfterDuration, }) { - final legacyPath = fileStoragePath?.path; - this.fileStorageLocation = fileStorageLocation ?? - (legacyPath is String ? Uri.tryParse(legacyPath) : null); + this.fileStorageLocation = fileStorageLocation; this.deleteFilesAfterDuration = deleteFilesAfterDuration; } diff --git a/lib/src/event.dart b/lib/src/event.dart index ca380267..43f4d27c 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -121,7 +121,7 @@ class Event extends MatrixEvent { // Mark event as failed to send if status is `sending` and event is older // than the timeout. This should not happen with the deprecated Moor // database! - if (status.isSending && room.client.database != null) { + if (status.isSending) { // Age of this event in milliseconds final age = DateTime.now().millisecondsSinceEpoch - originServerTs.millisecondsSinceEpoch; @@ -402,7 +402,7 @@ class Event extends MatrixEvent { throw Exception('Can only delete events which are not sent yet!'); } - await room.client.database?.removeEvent(eventId, room.id); + await room.client.database.removeEvent(eventId, room.id); if (room.lastEvent != null && room.lastEvent!.eventId == eventId) { final redactedBecause = Event.fromMatrixEvent( @@ -726,9 +726,6 @@ class Event extends MatrixEvent { // Is this file storeable? final thisInfoMap = getThumbnail ? thumbnailInfoMap : infoMap; final database = room.client.database; - if (database == null) { - return false; - } final storeable = thisInfoMap['size'] is int && thisInfoMap['size'] <= database.maxFileSize; @@ -772,13 +769,12 @@ class Event extends MatrixEvent { // Is this file storeable? final thisInfoMap = getThumbnail ? thumbnailInfoMap : infoMap; - var storeable = database != null && - thisInfoMap['size'] is int && + var storeable = thisInfoMap['size'] is int && thisInfoMap['size'] <= database.maxFileSize; Uint8List? uint8list; if (storeable) { - uint8list = await room.client.database?.getFile(mxcUrl); + uint8list = await room.client.database.getFile(mxcUrl); } // Download the file @@ -792,9 +788,7 @@ class Event extends MatrixEvent { .bodyBytes; uint8list = await downloadCallback(await mxcUrl.getDownloadUri(room.client)); - storeable = database != null && - storeable && - uint8list.lengthInBytes < database.maxFileSize; + storeable = storeable && uint8list.lengthInBytes < database.maxFileSize; if (storeable) { await database.storeFile( mxcUrl, diff --git a/lib/src/models/receipts.dart b/lib/src/models/receipts.dart index d7027c43..5bd1e000 100644 --- a/lib/src/models/receipts.dart +++ b/lib/src/models/receipts.dart @@ -284,7 +284,7 @@ class LatestReceiptState { // set the latest receipt to the one furthest down in the timeline, or if we don't know that, the newest ts. if (updatedTimelines.isEmpty) return; - final eventOrder = await room.client.database?.getEventIdList(room) ?? []; + final eventOrder = await room.client.database.getEventIdList(room); for (final timeline in updatedTimelines) { if (timeline.ownPrivate?.eventId == timeline.ownPublic?.eventId) { diff --git a/lib/src/room.dart b/lib/src/room.dart index e66fad1d..500e0aee 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -121,15 +121,13 @@ class Room { return; } final allStates = - await client.database?.getUnimportantRoomEventStatesForRoom( + await client.database.getUnimportantRoomEventStatesForRoom( client.importantStateEvents.toList(), this, ); - if (allStates != null) { - for (final state in allStates) { - setState(state); - } + for (final state in allStates) { + setState(state); } partial = false; } @@ -1237,7 +1235,7 @@ class Room { /// Call the Matrix API to forget this room if you already left it. Future forget() async { - await client.database?.forgetRoom(id); + await client.database.forgetRoom(id); await client.forgetRoom(id); // Update archived rooms, otherwise an archived room may still be in the // list after a forget room call @@ -1377,17 +1375,13 @@ class Room { ); } - if (client.database != null) { - await client.database?.transaction(() async { - if (storeInDatabase && direction == Direction.b) { - this.prev_batch = resp.end; - await client.database?.setRoomPrevBatch(resp.end, id, client); - } - await loadFn(); - }); - } else { + await client.database.transaction(() async { + if (storeInDatabase && direction == Direction.b) { + this.prev_batch = resp.end; + await client.database.setRoomPrevBatch(resp.end, id, client); + } await loadFn(); - } + }); return resp.chunk.length; } @@ -1478,7 +1472,7 @@ class Room { ].map((e) => Event.fromMatrixEvent(e, this)).toList(); // Try again to decrypt encrypted events but don't update the database. - if (encrypted && client.database != null && client.encryptionEnabled) { + if (encrypted && client.encryptionEnabled) { for (var i = 0; i < events.length; i++) { if (events[i].type == EventTypes.Encrypted && events[i].content['can_request_session'] == true) { @@ -1537,12 +1531,11 @@ class Room { var events = []; if (!isArchived) { - await client.database?.transaction(() async { - events = await client.database?.getEventList( - this, - limit: limit, - ) ?? - []; + await client.database.transaction(() async { + events = await client.database.getEventList( + this, + limit: limit, + ); }); } else { final archive = client.getArchiveRoomFromCache(id); @@ -1581,7 +1574,7 @@ class Room { final userIds = events.map((event) => event.senderId).toSet(); for (final userId in userIds) { if (getState(EventTypes.RoomMember, userId) != null) continue; - final dbUser = await client.database?.getUser(userId, this); + final dbUser = await client.database.getUser(userId, this); if (dbUser != null) setState(dbUser); } } @@ -1597,9 +1590,9 @@ class Room { chunk.events[i] = await client.encryption!.decryptRoomEvent( chunk.events[i], ); - } else if (client.database != null) { + } else { // else, we need the database - await client.database?.transaction(() async { + await client.database.transaction(() async { for (var i = 0; i < chunk.events.length; i++) { if (chunk.events[i].content['can_request_session'] == true) { chunk.events[i] = await client.encryption!.decryptRoomEvent( @@ -1666,7 +1659,7 @@ class Room { // events won't get written to memory in this case and someone new could // have joined, while someone else left, which might lead to the same // count in the completeness check. - final users = await client.database?.getUsers(this) ?? []; + final users = await client.database.getUsers(this); for (final user in users) { setState(user); } @@ -1697,7 +1690,7 @@ class Room { if (cache) { for (final user in users) { setState(user); // at *least* cache this in-memory - await client.database?.storeEventUpdate( + await client.database.storeEventUpdate( id, user, EventUpdateType.state, @@ -1775,8 +1768,8 @@ class Room { ); // Store user in database: - await client.database?.transaction(() async { - await client.database?.storeEventUpdate( + await client.database.transaction(() async { + await client.database.storeEventUpdate( id, foundUser, EventUpdateType.state, @@ -1812,7 +1805,7 @@ class Room { // If the room is not postloaded, check the database if (partial && foundUser == null) { - foundUser = await client.database?.getUser(mxID, this); + foundUser = await client.database.getUser(mxID, this); } // If not in the database, try fetching the member from the server @@ -1920,7 +1913,7 @@ class Room { /// found. Returns null if not found anywhere. Future getEventById(String eventID) async { try { - final dbEvent = await client.database?.getEventById(eventID, this); + final dbEvent = await client.database.getEventById(eventID, this); if (dbEvent != null) return dbEvent; final matrixEvent = await client.getOneRoomEvent(id, eventID); final event = Event.fromMatrixEvent(matrixEvent, this); @@ -2393,13 +2386,9 @@ class Room { SyncUpdate syncUpdate, { Direction? direction, }) async { - if (client.database != null) { - await client.database?.transaction(() async { - await client.handleSync(syncUpdate, direction: direction); - }); - } else { + await client.database.transaction(() async { await client.handleSync(syncUpdate, direction: direction); - } + }); } /// Whether this is an extinct room which has been archived in favor of a new diff --git a/lib/src/timeline.dart b/lib/src/timeline.dart index 0d196c0e..885b10b4 100644 --- a/lib/src/timeline.dart +++ b/lib/src/timeline.dart @@ -145,7 +145,7 @@ class Timeline { // Look up for events in the database first. With fragmented view, we should delete the database cache final eventsFromStore = isFragmentedTimeline ? null - : await room.client.database?.getEventList( + : await room.client.database.getEventList( room, start: events.length, limit: historyCount, @@ -161,7 +161,7 @@ class Timeline { continue; } final dbUser = - await room.client.database?.getUser(event.senderId, room); + await room.client.database.getUser(event.senderId, room); if (dbUser != null) room.setState(dbUser); } @@ -274,8 +274,7 @@ class Timeline { if (allowNewEvent) { Logs().d('We now allow sync update into the timeline.'); newEvents.addAll( - await room.client.database?.getEventList(room, onlySending: true) ?? - [], + await room.client.database.getEventList(room, onlySending: true), ); } } @@ -419,11 +418,7 @@ class Timeline { } } - if (room.client.database != null) { - await room.client.database?.transaction(decryptFn); - } else { - await decryptFn(); - } + await room.client.database.transaction(decryptFn); if (decryptAtLeastOneEvent) onUpdate?.call(); } @@ -664,12 +659,11 @@ class Timeline { // Search in database var start = events.length; while (true) { - final eventsFromStore = await room.client.database?.getEventList( - room, - start: start, - limit: requestHistoryCount, - ) ?? - []; + final eventsFromStore = await room.client.database.getEventList( + room, + start: start, + limit: requestHistoryCount, + ); if (eventsFromStore.isEmpty) break; start += eventsFromStore.length; for (final event in eventsFromStore) { diff --git a/lib/src/utils/device_keys_list.dart b/lib/src/utils/device_keys_list.dart index 2aecf13a..a2e81cc5 100644 --- a/lib/src/utils/device_keys_list.dart +++ b/lib/src/utils/device_keys_list.dart @@ -426,7 +426,7 @@ class CrossSigningKey extends SignableKey { } await super.setVerified(newVerified, sign); await client.database - ?.setVerifiedUserCrossSigningKey(newVerified, userId, publicKey!); + .setVerifiedUserCrossSigningKey(newVerified, userId, publicKey!); } @override @@ -436,7 +436,7 @@ class CrossSigningKey extends SignableKey { } _blocked = newBlocked; await client.database - ?.setBlockedUserCrossSigningKey(newBlocked, userId, publicKey!); + .setBlockedUserCrossSigningKey(newBlocked, userId, publicKey!); } CrossSigningKey.fromMatrixCrossSigningKey( @@ -513,7 +513,7 @@ class DeviceKeys extends SignableKey { } await super.setVerified(newVerified, sign); await client.database - ?.setVerifiedUserDeviceKey(newVerified, userId, deviceId!); + .setVerifiedUserDeviceKey(newVerified, userId, deviceId!); } @override @@ -524,7 +524,7 @@ class DeviceKeys extends SignableKey { } _blocked = newBlocked; await client.database - ?.setBlockedUserDeviceKey(newBlocked, userId, deviceId!); + .setBlockedUserDeviceKey(newBlocked, userId, deviceId!); } DeviceKeys.fromMatrixDeviceKeys( diff --git a/test/client_test.dart b/test/client_test.dart index c8cf4906..b50999cb 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -79,7 +79,7 @@ void main() { final client = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: await getDatabase(), ); expect(client.isLogged(), false); final Set initStates = {}; @@ -112,7 +112,7 @@ void main() { matrix = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: await getDatabase(), ); final eventUpdateListFuture = matrix.onTimelineEvent.stream.toList(); final toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList(); @@ -369,10 +369,10 @@ void main() { final key = 'abc def!/_-'; await matrix.setAccountData(matrix.userID!, key, content); - final dbContent = await matrix.database?.getAccountData(); + final dbContent = await matrix.database.getAccountData(); expect(matrix.accountData[key]?.content, content); - expect(dbContent?[key]?.content, content); + expect(dbContent[key]?.content, content); }); test('roomAccountData', () async { @@ -383,15 +383,15 @@ void main() { final key = 'abc def!/_-'; final roomId = '!726s6s6q:example.com'; await matrix.setAccountDataPerRoom(matrix.userID!, roomId, key, content); - final roomFromList = (await matrix.database?.getRoomList(matrix)) - ?.firstWhere((room) => room.id == roomId); - final roomFromDb = await matrix.database?.getSingleRoom(matrix, roomId); + final roomFromList = (await matrix.database.getRoomList(matrix)) + .firstWhere((room) => room.id == roomId); + final roomFromDb = await matrix.database.getSingleRoom(matrix, roomId); expect( matrix.getRoomById(roomId)?.roomAccountData[key]?.content, content, ); - expect(roomFromList?.roomAccountData[key]?.content, content); + expect(roomFromList.roomAccountData[key]?.content, content); expect( roomFromDb?.roomAccountData[key]?.content, content, @@ -418,7 +418,7 @@ void main() { matrix = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: await getDatabase(), ); expect(matrix.homeserver, null); @@ -504,7 +504,7 @@ void main() { matrix = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: await getDatabase(), ); await matrix.checkHomeserver( @@ -912,14 +912,14 @@ void main() { ); expect(matrix.onUserProfileUpdate.value, '@alice:example.com'); final cachedProfileFromDb = - await matrix.database?.getUserProfile('@alice:example.com'); + await matrix.database.getUserProfile('@alice:example.com'); expect(cachedProfileFromDb?.outdated, true); }); test('joinAfterInviteMembership', () async { final client = await getClient(); await client.abortSync(); client.rooms.clear(); - await client.database?.clearCache(); + await client.database.clearCache(); await client.handleSync( SyncUpdate.fromJson( @@ -955,7 +955,7 @@ void main() { await client.abortSync(); client.rooms.clear(); - await client.database?.clearCache(); + await client.database.clearCache(); await client.dispose(closeDatabase: true); }); test('leaveThenInvite should be invited', () async { @@ -967,7 +967,7 @@ void main() { final client = await getClient(); await client.abortSync(); client.rooms.clear(); - await client.database?.clearCache(); + await client.database.clearCache(); final roomId = '!inviteLeaveRoom:example.com'; await client.handleSync( @@ -1015,14 +1015,14 @@ void main() { await client.abortSync(); client.rooms.clear(); - await client.database?.clearCache(); + await client.database.clearCache(); await client.dispose(closeDatabase: true); }); test('ownProfile', () async { final client = await getClient(); await client.abortSync(); client.rooms.clear(); - await client.database?.clearCache(); + await client.database.clearCache(); await client.handleSync( SyncUpdate.fromJson( jsonDecode( @@ -1394,11 +1394,11 @@ void main() { ); }); test('Test the fake store api', () async { - final database = await getDatabase(null); + final database = await getDatabase(); final client1 = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: (_) => database, + database: database, ); await client1.init( @@ -1418,7 +1418,7 @@ void main() { final client2 = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: (_) => database, + database: database, ); await client2.init(); @@ -1470,8 +1470,8 @@ void main() { await client.uploadContent(Uint8List(0), filename: 'file.jpeg'); expect(response.toString(), 'mxc://example.com/AQwafuaFswefuhsfAFAgsw'); expect( - await client.database?.getFile(response) != null, - client.database?.supportsFileStoring, + await client.database.getFile(response) != null, + client.database.supportsFileStoring, ); await client.dispose(closeDatabase: true); }); @@ -1509,7 +1509,7 @@ void main() { FakeMatrixApi.expectedAccessToken = null; expect(client.accessToken, 'a_new_token'); expect(softLoggedOut, 1); - final storedClient = await client.database?.getClient(client.clientName); + final storedClient = await client.database.getClient(client.clientName); expect(storedClient?.tryGet('token'), 'a_new_token'); expect( storedClient?.tryGet('refresh_token'), @@ -1580,11 +1580,11 @@ void main() { }); test('Database Migration', () async { - final firstDatabase = await getDatabase(null); + final firstDatabase = await getDatabase(); final firstClient = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: (_) => firstDatabase, + database: firstDatabase, ); FakeMatrixApi.client = firstClient; await firstClient.checkHomeserver( @@ -1605,7 +1605,7 @@ void main() { final newClient = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: await getDatabase(), legacyDatabaseBuilder: (_) => firstDatabase, ); final Set initStates = {}; @@ -1621,7 +1621,7 @@ void main() { await newClient.dispose(closeDatabase: false); await firstDatabase.close(); - final sameOldFirstDatabase = await getDatabase(null); + final sameOldFirstDatabase = await getDatabase(); expect(await sameOldFirstDatabase.getClient('testclient'), null); }); @@ -1629,7 +1629,7 @@ void main() { final client = Client( 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: await getDatabase(), ) ..accessToken = '1234' ..baseUri = Uri.parse('https://fakeserver.notexisting'); @@ -1664,8 +1664,8 @@ void main() { expect(event?.room.name, 'TestRoomName'); expect(event?.room.canonicalAlias, '#testalias:blaaa'); final storedEvent = - await client.database?.getEventById('123', event!.room); - expect(storedEvent?.eventId, event?.eventId); + await client.database.getEventById('123', event!.room); + expect(storedEvent?.eventId, event.eventId); event = await client.getEventByPushNotification( PushNotification( @@ -1680,8 +1680,8 @@ void main() { expect(event?.messageType, 'm.text'); expect(event?.type, 'm.room.message'); final storedEvent2 = await client.database - ?.getEventById('143273582443PhrSn:example.org', event!.room); - expect(storedEvent2?.eventId, event?.eventId); + .getEventById('143273582443PhrSn:example.org', event!.room); + expect(storedEvent2?.eventId, event.eventId); }); test('Rooms and archived rooms getter', () async { @@ -1738,7 +1738,7 @@ void main() { () async { final customClient = Client( 'failclient', - databaseBuilder: getMatrixSdkDatabase, + database: await getMatrixSdkDatabase(), ); try { await customClient.init( diff --git a/test/database_api_test.dart b/test/database_api_test.dart index 7a359da1..5d57b9c3 100644 --- a/test/database_api_test.dart +++ b/test/database_api_test.dart @@ -44,7 +44,7 @@ void main() { late int toDeviceQueueIndex; test('Setup', () async { - database = await databaseBuilder.value(null); + database = await databaseBuilder.value(); }); test('transaction', () async { var counter = 0; @@ -105,29 +105,50 @@ void main() { 'limited_timeline': false, 'membership': Membership.join, }); - final client = Client('testclient'); + final client = Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ); await database.storeRoomUpdate('!testroom', roomUpdate, null, client); final rooms = await database.getRoomList(client); expect(rooms.single.id, '!testroom'); }); test('getRoomList', () async { - final room = - await database.getSingleRoom(Client('testclient'), '!testroom'); + final room = await database.getSingleRoom( + Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + '!testroom', + ); expect(room?.id, '!testroom'); }); test('getRoomList', () async { - final list = await database.getRoomList(Client('testclient')); + final list = await database.getRoomList( + Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ); expect(list.single.id, '!testroom'); }); test('setRoomPrevBatch', () async { - final client = Client('testclient'); + final client = Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ); await database.setRoomPrevBatch('1234', '!testroom', client); final rooms = await database.getRoomList(client); expect(rooms.single.prev_batch, '1234'); }); test('forgetRoom', () async { await database.forgetRoom('!testroom'); - final rooms = await database.getRoomList(Client('testclient')); + final rooms = await database.getRoomList( + Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ); expect(rooms.isEmpty, true); }); test('getClient', () async { @@ -238,12 +259,18 @@ void main() { }, ), EventUpdateType.timeline, - Client('testclient'), + Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), ); }); test('storeEventUpdate (state)', () async { final roomid = '!testrooma:example.com'; - final client = Client('testclient'); + final client = Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ); await database.storeRoomUpdate( roomid, @@ -376,26 +403,50 @@ void main() { test('getEventById', () async { final event = await database.getEventById( '\$event:example.com', - Room(id: '!testroom:example.com', client: Client('testclient')), + Room( + id: '!testroom:example.com', + client: Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ), ); expect(event?.type, EventTypes.Message); }); test('getEventList', () async { final events = await database.getEventList( - Room(id: '!testroom:example.com', client: Client('testclient')), + Room( + id: '!testroom:example.com', + client: Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ), ); expect(events.single.type, EventTypes.Message); }); test('getUser', () async { final user = await database.getUser( '@bob:example.org', - Room(id: '!testroom:example.com', client: Client('testclient')), + Room( + id: '!testroom:example.com', + client: Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ), ); expect(user, null); }); test('getUsers', () async { final users = await database.getUsers( - Room(id: '!testroom:example.com', client: Client('testclient')), + Room( + id: '!testroom:example.com', + client: Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ), ); expect(users.isEmpty, true); }); @@ -406,7 +457,13 @@ void main() { ); final event = await database.getEventById( '\$event:example.com', - Room(id: '!testroom:example.com', client: Client('testclient')), + Room( + id: '!testroom:example.com', + client: Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ), ); expect(event, null); }); @@ -568,12 +625,23 @@ void main() { test('getUnimportantRoomEventStatesForRoom', () async { final events = await database.getUnimportantRoomEventStatesForRoom( ['events'], - Room(id: '!mep', client: Client('testclient')), + Room( + id: '!mep', + client: Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ), ); expect(events.isEmpty, true); }); test('getUserDeviceKeys', () async { - await database.getUserDeviceKeys(Client('testclient')); + await database.getUserDeviceKeys( + Client( + 'testclient', + database: await getMatrixSdkDatabase(), + ), + ); }); test('storeUserCrossSigningKey', () async { await database.storeUserCrossSigningKey( @@ -695,7 +763,7 @@ void main() { await database.close(); }); test('Delete', () async { - final database = await getMatrixSdkDatabase(null); + final database = await getMatrixSdkDatabase(); await database.storeAccountData( 'm.test.data', {'foo': 'bar'}, @@ -703,7 +771,7 @@ void main() { await database.delete(); // Check if previously stored data is gone: - final reopenedDatabase = await getMatrixSdkDatabase(null); + final reopenedDatabase = await getMatrixSdkDatabase(); final dump = await reopenedDatabase.getAccountData(); expect(dump.isEmpty, true); }); diff --git a/test/encryption/encrypt_decrypt_to_device_test.dart b/test/encryption/encrypt_decrypt_to_device_test.dart index e1f9bc56..2476617e 100644 --- a/test/encryption/encrypt_decrypt_to_device_test.dart +++ b/test/encryption/encrypt_decrypt_to_device_test.dart @@ -23,11 +23,11 @@ import 'package:matrix/matrix.dart'; import '../fake_client.dart'; import '../fake_database.dart'; -void main() { +void main() async { // key @othertest:fakeServer.notExisting const otherPickledOlmAccount = 'VWhVApbkcilKAEGppsPDf9nNVjaK8/IxT3asSR0sYg0S5KgbfE8vXEPwoiKBX2cEvwX3OessOBOkk+ZE7TTbjlrh/KEd31p8Wo+47qj0AP+Ky+pabnhi+/rTBvZy+gfzTqUfCxZrkzfXI9Op4JnP6gYmy7dVX2lMYIIs9WCO1jcmIXiXum5jnfXu1WLfc7PZtO2hH+k9CDKosOFaXRBmsu8k/BGXPSoWqUpvu6WpEG9t5STk4FeAzA'; - + final database = await getDatabase(); group('Encrypt/Decrypt to-device messages', tags: 'olm', () { Logs().level = Level.error; @@ -35,7 +35,7 @@ void main() { final otherClient = Client( 'othertestclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: database, ); late DeviceKeys device; late Map payload; diff --git a/test/encryption/key_verification_test.dart b/test/encryption/key_verification_test.dart index 6f506e12..06fafcd9 100644 --- a/test/encryption/key_verification_test.dart +++ b/test/encryption/key_verification_test.dart @@ -67,7 +67,7 @@ void main() async { client2 = Client( 'othertestclient', httpClient: FakeMatrixApi.currentApi!, - databaseBuilder: getDatabase, + database: await getDatabase(), ); await client2.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), diff --git a/test/encryption/olm_manager_test.dart b/test/encryption/olm_manager_test.dart index 984283e8..d6a7e06a 100644 --- a/test/encryption/olm_manager_test.dart +++ b/test/encryption/olm_manager_test.dart @@ -157,7 +157,7 @@ void main() { final deviceId = 'JLAFKJWSCS'; final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'; FakeMatrixApi.calledEndpoints.clear(); - await client.database!.setLastSentMessageUserDeviceKey( + await client.database.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.foxies', 'content': { @@ -187,7 +187,7 @@ void main() { // not encrypted FakeMatrixApi.calledEndpoints.clear(); - await client.database!.setLastSentMessageUserDeviceKey( + await client.database.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.foxies', 'content': { @@ -213,7 +213,7 @@ void main() { // device not found FakeMatrixApi.calledEndpoints.clear(); - await client.database!.setLastSentMessageUserDeviceKey( + await client.database.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.foxies', 'content': { @@ -241,7 +241,7 @@ void main() { // don't replay if the last event is m.dummy itself FakeMatrixApi.calledEndpoints.clear(); - await client.database!.setLastSentMessageUserDeviceKey( + await client.database.setLastSentMessageUserDeviceKey( json.encode({ 'type': 'm.dummy', 'content': {}, diff --git a/test/encryption/online_key_backup_test.dart b/test/encryption/online_key_backup_test.dart index fffb8df9..0774f436 100644 --- a/test/encryption/online_key_backup_test.dart +++ b/test/encryption/online_key_backup_test.dart @@ -111,7 +111,7 @@ void main() { sessionPayload, forwarded: true, ); - var dbSessions = await client.database!.getInboundGroupSessionsToUpload(); + var dbSessions = await client.database.getInboundGroupSessionsToUpload(); expect(dbSessions.isNotEmpty, true); await client.encryption!.keyManager.uploadInboundGroupSessions(); await FakeMatrixApi.firstWhereValue( @@ -119,7 +119,7 @@ void main() { ); final payload = FakeMatrixApi .calledEndpoints['/client/v3/room_keys/keys?version=5']!.first; - dbSessions = await client.database!.getInboundGroupSessionsToUpload(); + dbSessions = await client.database.getInboundGroupSessionsToUpload(); expect(dbSessions.isEmpty, true); final onlineKeys = RoomKeys.fromJson(json.decode(payload)); diff --git a/test/event_test.dart b/test/event_test.dart index 8c1d4998..d95114bd 100644 --- a/test/event_test.dart +++ b/test/event_test.dart @@ -25,8 +25,15 @@ import 'package:matrix/encryption.dart'; import 'package:matrix/matrix.dart'; import 'package:matrix/src/models/timeline_chunk.dart'; import 'fake_client.dart'; +import 'fake_database.dart'; + +void main() async { + final client = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); -void main() { /// All Tests related to the Event group('Event', () { Logs().level = Level.error; @@ -51,7 +58,6 @@ void main() { 'status': EventStatus.synced.intValue, 'content': contentJson, }; - final client = Client('testclient', httpClient: FakeMatrixApi()); final room = Room(id: '!testroom:example.abc', client: client); final event = Event.fromJson( jsonObj, @@ -221,7 +227,13 @@ void main() { ]; for (final testType in testTypes) { redactJsonObj['type'] = testType; - final room = Room(id: '1234', client: Client('testclient')); + final room = Room( + id: '1234', + client: Client( + 'testclient', + database: await getDatabase(), + ), + ); final redactionEventJson = { 'content': {'reason': 'Spamming'}, 'event_id': '143273582443PhrSn:example.org', @@ -248,7 +260,13 @@ void main() { test('remove', () async { final event = Event.fromJson( jsonObj, - Room(id: '1234', client: Client('testclient')), + Room( + id: '1234', + client: Client( + 'testclient', + database: await getDatabase(), + ), + ), ); expect(() async => await event.cancelSend(), throwsException); event.status = EventStatus.sending; @@ -258,7 +276,11 @@ void main() { }); test('sendAgain', () async { - final matrix = Client('testclient', httpClient: FakeMatrixApi()); + final matrix = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); await matrix.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), checkWellKnown: false, @@ -283,7 +305,11 @@ void main() { }); test('requestKey', tags: 'olm', () async { - final matrix = Client('testclient', httpClient: FakeMatrixApi()); + final matrix = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); await matrix.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), checkWellKnown: false, @@ -333,6 +359,7 @@ void main() { await matrix.dispose(closeDatabase: true); }); test('requestKey', tags: 'olm', () async { + final client = await getClient(); jsonObj['state_key'] = '@alice:example.com'; final event = Event.fromJson( jsonObj, @@ -355,7 +382,11 @@ void main() { await client.dispose(); }); test('getLocalizedBody, isEventKnown', () async { - final matrix = Client('testclient', httpClient: FakeMatrixApi()); + final matrix = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); final room = Room(id: '!1234:example.com', client: matrix); var event = Event.fromJson( { @@ -1167,7 +1198,11 @@ void main() { }); test('getLocalizedBody, parameters', () async { - final matrix = Client('testclient', httpClient: FakeMatrixApi()); + final matrix = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); final room = Room(id: '!1234:example.com', client: matrix); var event = Event.fromJson( { @@ -2477,7 +2512,7 @@ void main() { ); expect( await event.isAttachmentInLocalStore(), - event.room.client.database?.supportsFileStoring, + event.room.client.database.supportsFileStoring, ); expect(buffer.bytes, FILE_BUFF); expect(serverHits, 1); @@ -2487,7 +2522,7 @@ void main() { expect(buffer.bytes, FILE_BUFF); expect( serverHits, - event.room.client.database!.supportsFileStoring ? 1 : 2, + event.room.client.database.supportsFileStoring ? 1 : 2, ); await room.client.dispose(closeDatabase: true); @@ -2530,12 +2565,12 @@ void main() { ); expect( await event.isAttachmentInLocalStore(), - event.room.client.database?.supportsFileStoring, + event.room.client.database.supportsFileStoring, ); expect(buffer.bytes, FILE_BUFF); expect(serverHits, 1); - if (event.room.client.database?.supportsFileStoring == true) { + if (event.room.client.database.supportsFileStoring == true) { buffer = await event.downloadAndDecryptAttachment( downloadCallback: downloadCallback, fromLocalStoreOnly: true, diff --git a/test/fake_client.dart b/test/fake_client.dart index 352874e2..a6afe5aa 100644 --- a/test/fake_client.dart +++ b/test/fake_client.dart @@ -35,8 +35,7 @@ Future getClient({ logLevel: Level.verbose, 'testclient', httpClient: FakeMatrixApi(), - databaseBuilder: (client) => - getDatabase(client, databasePath: databasePath), + database: await getDatabase(databasePath: databasePath), onSoftLogout: (client) => client.refreshAccessToken(), sendTimelineEventTimeout: sendTimelineEventTimeout, ); @@ -63,7 +62,7 @@ Future getOtherClient() async { final client = Client( 'othertestclient', httpClient: FakeMatrixApi(), - databaseBuilder: getDatabase, + database: await getDatabase(), ); FakeMatrixApi.client = client; await client.checkHomeserver( diff --git a/test/fake_database.dart b/test/fake_database.dart index 9f9023c8..a389e570 100644 --- a/test/fake_database.dart +++ b/test/fake_database.dart @@ -20,23 +20,18 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:matrix/matrix.dart'; -Future getDatabase(Client? c, {String? databasePath}) => - getMatrixSdkDatabase(c, path: databasePath); +Future getDatabase({String? databasePath}) => + getMatrixSdkDatabase(path: databasePath); // ignore: deprecated_member_use_from_same_package -Future getMatrixSdkDatabase( - Client? c, { +Future getMatrixSdkDatabase({ String? path, -}) async { - final database = await databaseFactoryFfi.openDatabase( - path ?? ':memory:', - options: OpenDatabaseOptions(singleInstance: false), - ); - final db = MatrixSdkDatabase( - 'unit_test.${c?.hashCode}', - database: database, - sqfliteFactory: databaseFactoryFfi, - ); - await db.open(); - return db; -} +}) async => + MatrixSdkDatabase.init( + 'unit_test.${DateTime.now().millisecondsSinceEpoch}', + database: await databaseFactoryFfi.openDatabase( + path ?? ':memory:', + options: OpenDatabaseOptions(singleInstance: false), + ), + sqfliteFactory: databaseFactoryFfi, + ); diff --git a/test/matrix_database_test.dart b/test/matrix_database_test.dart index 4fb9834e..995c701e 100644 --- a/test/matrix_database_test.dart +++ b/test/matrix_database_test.dart @@ -25,9 +25,16 @@ import 'fake_database.dart'; void main() { group('Databse', () { Logs().level = Level.error; - final room = Room(id: '!room:blubb', client: Client('testclient')); + late final Room room; test('setupDatabase', () async { - final database = await getDatabase(null); + final database = await getDatabase(); + room = Room( + id: '!room:blubb', + client: Client( + 'testclient', + database: database, + ), + ); await database.insertClient( 'testclient', 'https://example.org', @@ -43,8 +50,8 @@ void main() { }); test('storeEventUpdate', () async { - final client = Client('testclient'); - final database = await getDatabase(client); + final database = await getDatabase(); + final client = Client('testclient', database: database); // store a simple update await database.storeEventUpdate( room.id, diff --git a/test/msc_extensions/timeline_export_test.dart b/test/msc_extensions/timeline_export_test.dart index f0709ed4..4508d809 100644 --- a/test/msc_extensions/timeline_export_test.dart +++ b/test/msc_extensions/timeline_export_test.dart @@ -17,7 +17,7 @@ class MockClient extends Client { this.serverEvents = const [], this.dbEvents = const [], this.throwError = false, - }); + }) : super(database: MockDatabase(dbEvents)); @override Future getRoomEvents( @@ -47,7 +47,7 @@ class MockClient extends Client { } @override - DatabaseApi? get database => MockDatabase(dbEvents); + DatabaseApi get database => MockDatabase(dbEvents); } // MockDatabase: Simulates database access for the `TimelineExportExtension.export` diff --git a/test/mxc_uri_extension_test.dart b/test/mxc_uri_extension_test.dart index 541027d0..5638713f 100644 --- a/test/mxc_uri_extension_test.dart +++ b/test/mxc_uri_extension_test.dart @@ -19,13 +19,18 @@ import 'package:test/test.dart'; import 'package:matrix/matrix.dart'; +import 'fake_database.dart'; void main() { /// All Tests related to the MxContent group('MxContent', () { Logs().level = Level.error; test('Formatting', () async { - final client = Client('testclient', httpClient: FakeMatrixApi()); + final client = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); await client.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), checkWellKnown: false, @@ -56,7 +61,11 @@ void main() { ); }); test('other port', () async { - final client = Client('testclient', httpClient: FakeMatrixApi()); + final client = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); await client.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), checkWellKnown: false, @@ -88,7 +97,11 @@ void main() { ); }); test('other remote port', () async { - final client = Client('testclient', httpClient: FakeMatrixApi()); + final client = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); await client.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), checkWellKnown: false, @@ -108,7 +121,11 @@ void main() { ); }); test('Wrong scheme throw exception', () async { - final client = Client('testclient', httpClient: FakeMatrixApi()); + final client = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); await client.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), checkWellKnown: false, @@ -119,7 +136,11 @@ void main() { }); test('auth media fallback', () async { - final client = Client('testclient', httpClient: FakeMatrixApi()); + final client = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); await client.checkHomeserver( Uri.parse('https://fakeserverpriortoauthmedia.notexisting'), checkWellKnown: false, diff --git a/test/room_archived_test.dart b/test/room_archived_test.dart index 98b506f2..b9e65a4b 100644 --- a/test/room_archived_test.dart +++ b/test/room_archived_test.dart @@ -98,12 +98,12 @@ void main() async { final archiveRoom = client.getRoomById('!5345234234:example.com'); expect(archiveRoom != null, true); - final eventsFromStore = await client.database?.getEventList( + final eventsFromStore = await client.database.getEventList( archiveRoom!, start: 0, limit: Room.defaultHistoryCount, ); - expect(eventsFromStore?.isEmpty, true); + expect(eventsFromStore.isEmpty, true); }); test('discard room from archives when membership change', () async { diff --git a/test/room_test.dart b/test/room_test.dart index 1be822f9..d51d698c 100644 --- a/test/room_test.dart +++ b/test/room_test.dart @@ -1677,11 +1677,11 @@ void main() { // check if persisted in db final sentEventFromDB = - await matrix.database?.getEventById('older_event', room); + await matrix.database.getEventById('older_event', room); expect(sentEventFromDB?.eventId, 'older_event'); Room? roomFromDB; - roomFromDB = await matrix.database?.getSingleRoom(matrix, room.id); + roomFromDB = await matrix.database.getSingleRoom(matrix, room.id); expect(roomFromDB?.lastEvent?.eventId, 'older_event'); expect(room.lastEvent?.body, 'older_event'); @@ -1702,7 +1702,7 @@ void main() { expect(room.lastEvent?.eventId, 'event_too_large'); expect(room.lastEvent?.status, EventStatus.error); - roomFromDB = await matrix.database?.getSingleRoom(matrix, room.id); + roomFromDB = await matrix.database.getSingleRoom(matrix, room.id); expect(roomFromDB?.lastEvent?.eventId, 'event_too_large'); // force null because except would have caught it anyway @@ -1718,12 +1718,12 @@ void main() { // check if persisted in db final lastEventFromDB = - await matrix.database?.getEventById('event_too_large', room); + await matrix.database.getEventById('event_too_large', room); // null here because cancelSend removes event. expect(lastEventFromDB, null); - roomFromDB = await matrix.database?.getSingleRoom(matrix, room.id); + roomFromDB = await matrix.database.getSingleRoom(matrix, room.id); expect(roomFromDB?.partial, true); @@ -1733,7 +1733,7 @@ void main() { 'Cancelled sending message', ); - roomFromDB = await matrix.database?.getSingleRoom(matrix, room.id); + roomFromDB = await matrix.database.getSingleRoom(matrix, room.id); await roomFromDB?.postLoad(); expect(roomFromDB?.partial, false); diff --git a/test/user_test.dart b/test/user_test.dart index cc2e4ce5..8f778606 100644 --- a/test/user_test.dart +++ b/test/user_test.dart @@ -19,30 +19,37 @@ import 'package:test/test.dart'; import 'package:matrix/matrix.dart'; +import 'fake_database.dart'; -void main() { +void main() async { /// All Tests related to the Event group('User', () { - Logs().level = Level.error; - final client = Client('testclient', httpClient: FakeMatrixApi()); - final room = Room(id: '!localpart:server.abc', client: client); - final user1 = User( - '@alice:example.com', - membership: 'join', - displayName: 'Alice M', - avatarUrl: 'mxc://bla', - room: room, - ); - final user2 = User( - '@bob:example.com', - membership: 'join', - displayName: 'Bob', - avatarUrl: 'mxc://bla', - room: room, - ); - room.setState(user1); - room.setState(user2); + late Client client; + late Room room; + late User user1, user2; setUp(() async { + client = Client( + 'testclient', + httpClient: FakeMatrixApi(), + database: await getDatabase(), + ); + room = Room(id: '!localpart:server.abc', client: client); + user1 = User( + '@alice:example.com', + membership: 'join', + displayName: 'Alice M', + avatarUrl: 'mxc://bla', + room: room, + ); + user2 = User( + '@bob:example.com', + membership: 'join', + displayName: 'Bob', + avatarUrl: 'mxc://bla', + room: room, + ); + room.setState(user1); + room.setState(user2); await client.checkHomeserver( Uri.parse('https://fakeserver.notexisting'), checkWellKnown: false, diff --git a/test_driver/matrixsdk_test.dart b/test_driver/matrixsdk_test.dart index 9c783984..2945a39f 100644 --- a/test_driver/matrixsdk_test.dart +++ b/test_driver/matrixsdk_test.dart @@ -47,7 +47,7 @@ void main() => group( Logs().i('++++ Using homeserver $homeserverUri ++++'); Logs().i('++++ Login Alice at ++++'); - testClientA = Client('TestClientA', databaseBuilder: getDatabase); + testClientA = Client('TestClientA', database: await getDatabase()); await testClientA.checkHomeserver(homeserverUri); await testClientA.login( LoginType.mLoginPassword, @@ -57,7 +57,7 @@ void main() => group( expect(testClientA.encryptionEnabled, true); Logs().i('++++ Login Bob ++++'); - testClientB = Client('TestClientB', databaseBuilder: getDatabase); + testClientB = Client('TestClientB', database: await getDatabase()); await testClientB.checkHomeserver(homeserverUri); await testClientB.login( LoginType.mLoginPassword, @@ -341,7 +341,7 @@ void main() => group( Logs().i('++++ Login Bob in another client ++++'); final testClientC = - Client('TestClientC', databaseBuilder: getDatabase); + Client('TestClientC', database: await getDatabase()); await testClientC.checkHomeserver(homeserverUri); // We can't sign in using the displayname, since that breaks e2ee on dendrite: https://github.com/matrix-org/dendrite/issues/2914 await testClientC.login( @@ -493,7 +493,7 @@ void main() => group( Logs().i('++++ Using homeserver $homeserverUri ++++'); Logs().i('++++ Login Alice at ++++'); - testClientA = Client('TestClientA', databaseBuilder: getDatabase); + testClientA = Client('TestClientA', database: await getDatabase()); await testClientA.checkHomeserver(homeserverUri); await testClientA.login( LoginType.mLoginPassword, @@ -503,7 +503,7 @@ void main() => group( expect(testClientA.encryptionEnabled, true); Logs().i('++++ Login Bob ++++'); - testClientB = Client('TestClientB', databaseBuilder: getDatabase); + testClientB = Client('TestClientB', database: await getDatabase()); await testClientB.checkHomeserver(homeserverUri); await testClientB.login( LoginType.mLoginPassword, diff --git a/web_test/web/main.dart b/web_test/web/main.dart index 6873007d..d4ed65e0 100644 --- a/web_test/web/main.dart +++ b/web_test/web/main.dart @@ -1,6 +1,9 @@ import 'package:matrix/matrix.dart'; Future main() async { - final client = Client('web_test'); + final client = Client( + 'web_test', + database: await MatrixSdkDatabase.init('web_test'), + ); await client.init(); }