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