Store mailbox cache by AccountId

(cherry picked from commit 7804f19d27d65af855e145de1953df9a553f3ce0)
This commit is contained in:
dab246
2023-04-25 14:35:55 +07:00
committed by Dat Vu
parent 880c41b721
commit 1b7ce6b37a
13 changed files with 95 additions and 28 deletions
@@ -0,0 +1,29 @@
class TupleKey {
final List<String> parts;
TupleKey(
String key1,
[
String? key2,
String? key3
]
) : parts = [
key1,
if (key2 != null) key2,
if (key3 != null) key3,
];
const TupleKey.byParts(this.parts);
TupleKey.fromString(String multiKeyString) : parts = multiKeyString.split('|').toList();
@override
String toString() => parts.join('|');
@override
bool operator ==(other) => parts.toString() == other.toString();
@override
int get hashCode => Object.hashAll(parts);
}
@@ -26,7 +26,7 @@ abstract class MailboxDataSource {
Future<MailboxChangeResponse> getChanges(Session session, AccountId accountId, State sinceState);
Future<void> update({List<Mailbox>? updated, List<Mailbox>? created, List<MailboxId>? destroyed});
Future<void> update(AccountId accountId, {List<Mailbox>? updated, List<Mailbox>? created, List<MailboxId>? destroyed});
Future<Mailbox?> createNewMailbox(Session session, AccountId accountId, CreateNewMailboxRequest newMailboxRequest);
@@ -40,9 +40,9 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource {
}
@override
Future<void> update({List<Mailbox>? updated, List<Mailbox>? created, List<MailboxId>? destroyed}) {
Future<void> update(AccountId accountId, {List<Mailbox>? updated, List<Mailbox>? created, List<MailboxId>? destroyed}) {
return Future.sync(() async {
return await _mailboxCacheManager.update(updated: updated, created: created, destroyed: destroyed);
return await _mailboxCacheManager.update(accountId, updated: updated, created: created, destroyed: destroyed);
}).catchError(_exceptionThrower.throwException);
}
@@ -46,7 +46,7 @@ class MailboxDataSourceImpl extends MailboxDataSource {
}
@override
Future<void> update({List<Mailbox>? updated, List<Mailbox>? created, List<MailboxId>? destroyed}) {
Future<void> update(AccountId accountId, {List<Mailbox>? updated, List<Mailbox>? created, List<MailboxId>? destroyed}) {
throw UnimplementedError();
}
@@ -1,8 +0,0 @@
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart';
extension ListMailboxCacheExtension on List<MailboxCache> {
Map<String, MailboxCache> toMap() {
return { for (var mailboxCache in this) mailboxCache.id : mailboxCache };
}
}
@@ -0,0 +1,17 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/extensions/account_id_extensions.dart';
import 'package:model/extensions/mailbox_id_extension.dart';
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart';
extension ListMailboxExtension on List<Mailbox> {
Map<String, MailboxCache> toMapCache(AccountId accountId) {
return {
for (var mailbox in this)
TupleKey(mailbox.id!.asString, accountId.asString).toString() : mailbox.toMailboxCache()
};
}
}
@@ -0,0 +1,10 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/extensions/account_id_extensions.dart';
import 'package:model/extensions/mailbox_id_extension.dart';
import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
extension ListMailboxIdExtension on List<MailboxId> {
List<String> toCacheKeyList(AccountId accountId) => map((id) => TupleKey(id.asString, accountId.asString).toString()).toList();
}
@@ -1,11 +1,11 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/caching/mailbox_cache_client.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/list_mailbox_cache_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/list_mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/list_mailbox_id_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_cache_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/extensions/mailbox_extension.dart';
import 'package:tmail_ui_user/features/mailbox/data/model/mailbox_cache.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/exceptions/spam_report_exception.dart';
class MailboxCacheManager {
@@ -20,24 +20,26 @@ class MailboxCacheManager {
return mailboxList;
}
Future<void> update({List<Mailbox>? updated, List<Mailbox>? created, List<MailboxId>? destroyed}) async {
Future<void> update(
AccountId accountId, {
List<Mailbox>? updated,
List<Mailbox>? created,
List<MailboxId>? destroyed
}) async {
final mailboxCacheExist = await _mailboxCacheClient.isExistTable();
if (mailboxCacheExist) {
final updatedCacheMailboxes = updated
?.map((mailbox) => mailbox.toMailboxCache()).toList() ?? <MailboxCache>[];
final createdCacheMailboxes = created
?.map((mailbox) => mailbox.toMailboxCache()).toList() ?? <MailboxCache>[];
final destroyedCacheMailboxes = destroyed
?.map((mailboxId) => mailboxId.id.value).toList() ?? <String>[];
final updatedCacheMailboxes = updated?.toMapCache(accountId) ?? {};
final createdCacheMailboxes = created?.toMapCache(accountId) ?? {};
final destroyedCacheMailboxes = destroyed?.toCacheKeyList(accountId) ?? [];
await Future.wait([
_mailboxCacheClient.updateMultipleItem(updatedCacheMailboxes.toMap()),
_mailboxCacheClient.insertMultipleItem(createdCacheMailboxes.toMap()),
_mailboxCacheClient.updateMultipleItem(updatedCacheMailboxes),
_mailboxCacheClient.insertMultipleItem(createdCacheMailboxes),
_mailboxCacheClient.deleteMultipleItem(destroyedCacheMailboxes)
]);
} else {
final createdCacheMailboxes = created
?.map((mailbox) => mailbox.toMailboxCache()).toList() ?? <MailboxCache>[];
await _mailboxCacheClient.insertMultipleItem(createdCacheMailboxes.toMap());
final createdCacheMailboxes = created?.toMapCache(accountId) ?? {};
await _mailboxCacheClient.insertMultipleItem(createdCacheMailboxes);
}
}
@@ -64,6 +64,7 @@ class MailboxRepositoryImpl extends MailboxRepository {
await Future.wait([
mapDataSource[DataSourceType.local]!.update(
accountId,
updated: newMailboxUpdated,
created: changesResponse.created,
destroyed: changesResponse.destroyed),
@@ -75,7 +76,7 @@ class MailboxRepositoryImpl extends MailboxRepository {
final mailboxResponse = await mapDataSource[DataSourceType.network]!.getAllMailbox(session, accountId);
await Future.wait([
mapDataSource[DataSourceType.local]!.update(created: mailboxResponse.mailboxes),
mapDataSource[DataSourceType.local]!.update(accountId, created: mailboxResponse.mailboxes),
if (mailboxResponse.state != null)
stateDataSource.saveState(mailboxResponse.state!.toStateCache(StateType.mailbox)),
]);
@@ -135,6 +136,7 @@ class MailboxRepositoryImpl extends MailboxRepository {
await Future.wait([
mapDataSource[DataSourceType.local]!.update(
accountId,
updated: newMailboxUpdated,
created: changesResponse.created,
destroyed: changesResponse.destroyed),
@@ -0,0 +1,6 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
extension AccountIdExtension on AccountId {
String get asString => id.value;
}
@@ -0,0 +1,5 @@
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
extension EmailIdExtension on EmailId {
String get asString => id.value;
}
@@ -23,4 +23,6 @@ extension MailboxIdExtension on MailboxId {
generatePath(): true,
});
}
String get asString => id.value;
}
+2
View File
@@ -55,6 +55,8 @@ export 'extensions/list_email_header_extension.dart';
export 'extensions/account_extension.dart';
export 'extensions/list_presentation_mailbox_extension.dart';
export 'extensions/list_identity_id_extension.dart';
export 'extensions/email_id_extensions.dart';
export 'extensions/account_id_extensions.dart';
// Identity
export 'identity/identity_request_dto.dart';
export 'mailbox/expand_mode.dart';