fix: Increment on sqlite level to hopefully fix "race conditions"
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:anitrack/src/data/anime.dart';
|
||||
import 'package:anitrack/src/data/manga.dart';
|
||||
import 'package:anitrack/src/service/migrations/0000_airing.dart';
|
||||
import 'package:anitrack/src/service/migrations/0000_score.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
|
||||
const animeTable = 'Anime';
|
||||
const mangaTable = 'Manga';
|
||||
@@ -53,6 +56,12 @@ class DatabaseService {
|
||||
late final Database _db;
|
||||
|
||||
Future<void> initialize() async {
|
||||
// Allow initializing the database on Windows and Linux as well.
|
||||
if (Platform.isLinux || Platform.isWindows) {
|
||||
sqfliteFfiInit();
|
||||
}
|
||||
databaseFactory = databaseFactoryFfi;
|
||||
|
||||
_db = await openDatabase(
|
||||
'anitrack.db',
|
||||
version: 3,
|
||||
@@ -113,6 +122,21 @@ class DatabaseService {
|
||||
);
|
||||
}
|
||||
|
||||
Future<AnimeTrackingData> incrementAnimeWatchCounter(AnimeTrackingData data, int value) async {
|
||||
final result = await _db.rawQuery(
|
||||
'UPDATE $animeTable SET episodesWatched = episodesWatched + $value WHERE id = ? RETURNING *',
|
||||
[
|
||||
data.id,
|
||||
],
|
||||
);
|
||||
|
||||
return result
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map(AnimeTrackingData.fromJson)
|
||||
.toList()
|
||||
.first;
|
||||
}
|
||||
|
||||
Future<void> deleteAnime(String id) async {
|
||||
await _db.delete(
|
||||
animeTable,
|
||||
@@ -145,4 +169,19 @@ class DatabaseService {
|
||||
whereArgs: [id],
|
||||
);
|
||||
}
|
||||
|
||||
Future<MangaTrackingData> incrementMangaReadChapters(MangaTrackingData data, int value) async {
|
||||
final result = await _db.rawQuery(
|
||||
'UPDATE $mangaTable SET episodesWatched = chaptersRead + $value WHERE id = ? RETURNING *',
|
||||
[
|
||||
data.id,
|
||||
],
|
||||
);
|
||||
|
||||
return result
|
||||
.cast<Map<String, dynamic>>()
|
||||
.map(MangaTrackingData.fromJson)
|
||||
.toList()
|
||||
.first;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,19 +122,14 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
||||
if (anime.episodesTotal != null &&
|
||||
anime.episodesWatched + 1 > anime.episodesTotal!) return;
|
||||
|
||||
final newAnime = await GetIt.I.get<DatabaseService>().incrementAnimeWatchCounter(anime, 1);
|
||||
final newList = List<AnimeTrackingData>.from(state.animes);
|
||||
final newAnime = anime.copyWith(
|
||||
episodesWatched: anime.episodesWatched + 1,
|
||||
);
|
||||
newList[index] = newAnime;
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
animes: newList,
|
||||
),
|
||||
);
|
||||
|
||||
await GetIt.I.get<DatabaseService>().updateAnime(newAnime);
|
||||
}
|
||||
|
||||
Future<void> _onAnimeDecremented(
|
||||
@@ -147,19 +142,15 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
||||
final anime = state.animes[index];
|
||||
if (anime.episodesWatched - 1 < 0) return;
|
||||
|
||||
final newList = List<AnimeTrackingData>.from(state.animes);
|
||||
final newAnime = anime.copyWith(
|
||||
episodesWatched: anime.episodesWatched - 1,
|
||||
);
|
||||
newList[index] = newAnime;
|
||||
|
||||
final newAnime = await GetIt.I.get<DatabaseService>().incrementAnimeWatchCounter(anime, -1);
|
||||
final newList = List<AnimeTrackingData>.from(state.animes);
|
||||
newList[index] = newAnime;
|
||||
emit(
|
||||
state.copyWith(
|
||||
animes: newList,
|
||||
),
|
||||
);
|
||||
|
||||
await GetIt.I.get<DatabaseService>().updateAnime(newAnime);
|
||||
}
|
||||
|
||||
Future<void> _onAnimesLoaded(
|
||||
@@ -228,24 +219,19 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
||||
if (manga.chaptersTotal != null &&
|
||||
manga.chaptersRead + 1 > manga.chaptersTotal!) return;
|
||||
|
||||
final newManga = await GetIt.I.get<DatabaseService>().incrementMangaReadChapters(manga, 1);
|
||||
final newList = List<MangaTrackingData>.from(state.mangas);
|
||||
final newManga = manga.copyWith(
|
||||
chaptersRead: manga.chaptersRead + 1,
|
||||
);
|
||||
newList[index] = newManga;
|
||||
|
||||
// Update the cache
|
||||
final cacheIndex = _mangas.indexWhere((m) => m.id == event.id);
|
||||
assert(cacheIndex != -1, 'The manga must exist');
|
||||
_mangas[cacheIndex] = newManga;
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
mangas: newList,
|
||||
),
|
||||
);
|
||||
|
||||
await GetIt.I.get<DatabaseService>().updateManga(newManga);
|
||||
// Update the cache
|
||||
final cacheIndex = _mangas.indexWhere((m) => m.id == event.id);
|
||||
assert(cacheIndex != -1, 'The manga must exist');
|
||||
_mangas[cacheIndex] = newManga;
|
||||
}
|
||||
|
||||
Future<void> _onMangaDecremented(
|
||||
@@ -258,24 +244,19 @@ class AnimeListBloc extends Bloc<AnimeListEvent, AnimeListState> {
|
||||
final manga = state.mangas[index];
|
||||
if (manga.chaptersRead - 1 < 0) return;
|
||||
|
||||
final newManga = await GetIt.I.get<DatabaseService>().incrementMangaReadChapters(manga, -1);
|
||||
final newList = List<MangaTrackingData>.from(state.mangas);
|
||||
final newManga = manga.copyWith(
|
||||
chaptersRead: manga.chaptersRead - 1,
|
||||
);
|
||||
newList[index] = newManga;
|
||||
|
||||
// Update the cache
|
||||
final cacheIndex = _mangas.indexWhere((m) => m.id == event.id);
|
||||
assert(cacheIndex != -1, 'The manga must exist');
|
||||
_mangas[cacheIndex] = newManga;
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
mangas: newList,
|
||||
),
|
||||
);
|
||||
|
||||
await GetIt.I.get<DatabaseService>().updateManga(newManga);
|
||||
// Update the cache
|
||||
final cacheIndex = _mangas.indexWhere((m) => m.id == event.id);
|
||||
assert(cacheIndex != -1, 'The manga must exist');
|
||||
_mangas[cacheIndex] = newManga;
|
||||
}
|
||||
|
||||
Future<void> _onAnimeUpdated(
|
||||
|
||||
Reference in New Issue
Block a user