Skip to content
This repository was archived by the owner on Apr 3, 2025. It is now read-only.

Commit 9960124

Browse files
committed
fix(database): prevent deadlock in database deletion actions
1 parent aed7e85 commit 9960124

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

lib/database/database.dart

+24-7
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@ import 'package:lunasea/database/models/profile.dart';
33
import 'package:lunasea/database/table.dart';
44
import 'package:lunasea/database/tables/bios.dart';
55
import 'package:lunasea/database/tables/lunasea.dart';
6+
import 'package:lunasea/system/filesystem/filesystem.dart';
7+
import 'package:lunasea/system/logger.dart';
68
import 'package:lunasea/system/platform.dart';
79
import 'package:lunasea/vendor.dart';
810

911
class LunaDatabase {
1012
static const String _DATABASE_LEGACY_PATH = 'database';
1113
static const String _DATABASE_PATH = 'LunaSea/database';
1214

13-
String get _path {
15+
String get path {
1416
if (LunaPlatform.isWindows || LunaPlatform.isLinux) return _DATABASE_PATH;
1517
return _DATABASE_LEGACY_PATH;
1618
}
1719

1820
Future<void> initialize() async {
19-
await Hive.initFlutter(_path);
21+
await Hive.initFlutter(path);
2022
LunaTable.register();
2123
await open();
2224
}
@@ -25,13 +27,28 @@ class LunaDatabase {
2527
try {
2628
await LunaBox.open();
2729
if (LunaBox.profiles.isEmpty) await bootstrap();
28-
} catch (error) {
29-
for (final box in LunaBox.values) {
30-
await Hive.deleteBoxFromDisk(box.key);
31-
}
32-
30+
} catch (error, stack) {
31+
await nuke();
3332
await LunaBox.open();
3433
await bootstrap(databaseCorruption: true);
34+
35+
LunaLogger().error(
36+
'Database corruption detected',
37+
error,
38+
stack,
39+
);
40+
}
41+
}
42+
43+
Future<void> nuke() async {
44+
await Hive.close();
45+
46+
for (final box in LunaBox.values) {
47+
await Hive.deleteBoxFromDisk(box.key, path: path);
48+
}
49+
50+
if (LunaFileSystem.isSupported) {
51+
await LunaFileSystem().nuke();
3552
}
3653
}
3754

lib/system/filesystem/filesystem.dart

+1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ abstract class LunaFileSystem {
1717

1818
Future<bool> save(BuildContext context, String name, List<int> data);
1919
Future<LunaFile?> read(BuildContext context, List<String> extensions);
20+
Future<void> nuke();
2021
}

lib/system/filesystem/platform/filesystem_io.dart

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:io';
22
import 'package:file_picker/file_picker.dart';
33
import 'package:flutter/material.dart';
4+
import 'package:lunasea/database/database.dart';
45
import 'package:lunasea/vendor.dart';
56
import 'package:path_provider/path_provider.dart';
67
import 'package:share_plus/share_plus.dart';
@@ -21,7 +22,20 @@ LunaFileSystem getFileSystem() {
2122
throw UnsupportedError('LunaFileSystem unsupported');
2223
}
2324

24-
class _Desktop implements LunaFileSystem {
25+
abstract class _Shared implements LunaFileSystem {
26+
@override
27+
Future<void> nuke() async {
28+
final subpath = LunaDatabase().path;
29+
final appDocDir = await getApplicationDocumentsDirectory();
30+
final database = Directory('${appDocDir.path}/$subpath');
31+
32+
if (database.existsSync()) {
33+
database.deleteSync(recursive: true);
34+
}
35+
}
36+
}
37+
38+
class _Desktop extends _Shared {
2539
@override
2640
Future<bool> save(BuildContext context, String name, List<int> data) async {
2741
try {
@@ -69,7 +83,7 @@ class _Desktop implements LunaFileSystem {
6983
}
7084
}
7185

72-
class _Mobile implements LunaFileSystem {
86+
class _Mobile extends _Shared {
7387
@override
7488
Future<bool> save(BuildContext context, String name, List<int> data) async {
7589
try {

0 commit comments

Comments
 (0)