feat: export database option (#20098)

This commit is contained in:
Alex 2025-07-23 09:40:16 -05:00 committed by GitHub
parent 1a35a01149
commit 0174de19dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 81 additions and 0 deletions

View File

@ -1002,6 +1002,8 @@
"explorer": "Explorer", "explorer": "Explorer",
"export": "Export", "export": "Export",
"export_as_json": "Export as JSON", "export_as_json": "Export as JSON",
"export_database": "Export Database",
"export_database_description": "Export the SQLite database",
"extension": "Extension", "extension": "Extension",
"external": "External", "external": "External",
"external_libraries": "External Libraries", "external_libraries": "External Libraries",

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:drift/drift.dart' as drift_db; import 'package:drift/drift.dart' as drift_db;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
@ -10,6 +12,9 @@ import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart'; import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
import 'package:immich_mobile/providers/sync_status.provider.dart'; import 'package:immich_mobile/providers/sync_status.provider.dart';
import 'package:immich_mobile/widgets/settings/beta_sync_settings/entity_count_tile.dart'; import 'package:immich_mobile/widgets/settings/beta_sync_settings/entity_count_tile.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
class BetaSyncSettings extends HookConsumerWidget { class BetaSyncSettings extends HookConsumerWidget {
const BetaSyncSettings({ const BetaSyncSettings({
@ -69,6 +74,67 @@ class BetaSyncSettings extends HookConsumerWidget {
}); });
} }
Future<void> exportDatabase() async {
try {
// WAL Checkpoint to ensure all changes are written to the database
await ref
.read(driftProvider)
.customStatement("pragma wal_checkpoint(truncate)");
final documentsDir = await getApplicationDocumentsDirectory();
final dbFile = File(path.join(documentsDir.path, 'immich.sqlite'));
if (!await dbFile.exists()) {
if (context.mounted) {
context.scaffoldMessenger.showSnackBar(
SnackBar(
content: Text("Database file not found".t(context: context)),
),
);
}
return;
}
final timestamp = DateTime.now().millisecondsSinceEpoch;
final exportFile = File(
path.join(
documentsDir.path,
'immich_export_$timestamp.sqlite',
),
);
await dbFile.copy(exportFile.path);
await Share.shareXFiles(
[XFile(exportFile.path)],
text: 'Immich Database Export',
);
Future.delayed(const Duration(seconds: 30), () async {
if (await exportFile.exists()) {
await exportFile.delete();
}
});
if (context.mounted) {
context.scaffoldMessenger.showSnackBar(
SnackBar(
content:
Text("Database exported successfully".t(context: context)),
),
);
}
} catch (e) {
if (context.mounted) {
context.scaffoldMessenger.showSnackBar(
SnackBar(
content:
Text("Failed to export database: $e".t(context: context)),
),
);
}
}
}
return FutureBuilder<List<dynamic>>( return FutureBuilder<List<dynamic>>(
future: loadCounts(), future: loadCounts(),
builder: (context, snapshot) { builder: (context, snapshot) {
@ -232,6 +298,19 @@ class BetaSyncSettings extends HookConsumerWidget {
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
_SectionHeaderText(text: "actions".t(context: context)), _SectionHeaderText(text: "actions".t(context: context)),
ListTile(
title: Text(
"export_database".t(context: context),
style: const TextStyle(
fontWeight: FontWeight.w500,
),
),
subtitle: Text(
"export_database_description".t(context: context),
),
leading: const Icon(Icons.download),
onTap: exportDatabase,
),
ListTile( ListTile(
title: Text( title: Text(
"reset_sqlite".t(context: context), "reset_sqlite".t(context: context),