feat: migrate store to sqlite (#21078)

* add store entity and migration

* make store service take both isar and drift repos

* migrate and switch store on beta timeline state change

* chore: make drift variables final

* dispose old store before switching repos

* use store to update values for beta timeline

* change log service to use the proper store

* migrate store when beta already enabled

* use isar repository to check beta timeline in store service

* remove unused update method from store repo

* dispose after create

* change watchAll signature in store repo

* fix test

* rename init isar to initDB

* request user to close and reopen on beta migration

* fix tests

* handle empty version in migration

* wait for cache to be populated after migration

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
shenlong
2025-08-22 01:28:50 +05:30
committed by GitHub
parent ed3997d844
commit 6f4f79d8cc
26 changed files with 7907 additions and 169 deletions
@@ -44,7 +44,7 @@ void main() {
test('converts int', () async {
int? version = await sut.tryGet(StoreKey.version);
expect(version, isNull);
await sut.insert(StoreKey.version, _kTestVersion);
await sut.upsert(StoreKey.version, _kTestVersion);
version = await sut.tryGet(StoreKey.version);
expect(version, _kTestVersion);
});
@@ -52,7 +52,7 @@ void main() {
test('converts string', () async {
String? accessToken = await sut.tryGet(StoreKey.accessToken);
expect(accessToken, isNull);
await sut.insert(StoreKey.accessToken, _kTestAccessToken);
await sut.upsert(StoreKey.accessToken, _kTestAccessToken);
accessToken = await sut.tryGet(StoreKey.accessToken);
expect(accessToken, _kTestAccessToken);
});
@@ -60,7 +60,7 @@ void main() {
test('converts datetime', () async {
DateTime? backupFailedSince = await sut.tryGet(StoreKey.backupFailedSince);
expect(backupFailedSince, isNull);
await sut.insert(StoreKey.backupFailedSince, _kTestBackupFailed);
await sut.upsert(StoreKey.backupFailedSince, _kTestBackupFailed);
backupFailedSince = await sut.tryGet(StoreKey.backupFailedSince);
expect(backupFailedSince, _kTestBackupFailed);
});
@@ -68,7 +68,7 @@ void main() {
test('converts bool', () async {
bool? colorfulInterface = await sut.tryGet(StoreKey.colorfulInterface);
expect(colorfulInterface, isNull);
await sut.insert(StoreKey.colorfulInterface, _kTestColorfulInterface);
await sut.upsert(StoreKey.colorfulInterface, _kTestColorfulInterface);
colorfulInterface = await sut.tryGet(StoreKey.colorfulInterface);
expect(colorfulInterface, _kTestColorfulInterface);
});
@@ -76,7 +76,7 @@ void main() {
test('converts user', () async {
UserDto? user = await sut.tryGet(StoreKey.currentUser);
expect(user, isNull);
await sut.insert(StoreKey.currentUser, _kTestUser);
await sut.upsert(StoreKey.currentUser, _kTestUser);
user = await sut.tryGet(StoreKey.currentUser);
expect(user, _kTestUser);
});
@@ -108,10 +108,10 @@ void main() {
await _populateStore(db);
});
test('update()', () async {
test('upsert()', () async {
int? version = await sut.tryGet(StoreKey.version);
expect(version, _kTestVersion);
await sut.update(StoreKey.version, _kTestVersion + 10);
await sut.upsert(StoreKey.version, _kTestVersion + 10);
version = await sut.tryGet(StoreKey.version);
expect(version, _kTestVersion + 10);
});
@@ -126,22 +126,29 @@ void main() {
final stream = sut.watch(StoreKey.version);
expectLater(stream, emitsInOrder([_kTestVersion, _kTestVersion + 10]));
await pumpEventQueue();
await sut.update(StoreKey.version, _kTestVersion + 10);
await sut.upsert(StoreKey.version, _kTestVersion + 10);
});
test('watchAll()', () async {
final stream = sut.watchAll();
expectLater(
stream,
emitsInAnyOrder([
emits(const StoreDto<Object>(StoreKey.version, _kTestVersion)),
emits(StoreDto<Object>(StoreKey.backupFailedSince, _kTestBackupFailed)),
emits(const StoreDto<Object>(StoreKey.accessToken, _kTestAccessToken)),
emits(const StoreDto<Object>(StoreKey.colorfulInterface, _kTestColorfulInterface)),
emits(const StoreDto<Object>(StoreKey.version, _kTestVersion + 10)),
emitsInOrder([
[
const StoreDto<Object>(StoreKey.version, _kTestVersion),
StoreDto<Object>(StoreKey.backupFailedSince, _kTestBackupFailed),
const StoreDto<Object>(StoreKey.accessToken, _kTestAccessToken),
const StoreDto<Object>(StoreKey.colorfulInterface, _kTestColorfulInterface),
],
[
const StoreDto<Object>(StoreKey.version, _kTestVersion + 10),
StoreDto<Object>(StoreKey.backupFailedSince, _kTestBackupFailed),
const StoreDto<Object>(StoreKey.accessToken, _kTestAccessToken),
const StoreDto<Object>(StoreKey.colorfulInterface, _kTestColorfulInterface),
],
]),
);
await sut.update(StoreKey.version, _kTestVersion + 10);
await sut.upsert(StoreKey.version, _kTestVersion + 10);
});
});
}
@@ -14,6 +14,8 @@ import 'package:mocktail/mocktail.dart';
class MockStoreRepository extends Mock implements IsarStoreRepository {}
class MockDriftStoreRepository extends Mock implements DriftStoreRepository {}
class MockLogRepository extends Mock implements LogRepository {}
class MockIsarUserRepository extends Mock implements IsarUserRepository {}