mirror of
https://github.com/immich-app/immich.git
synced 2025-07-31 15:08:44 -04:00
feat: export database option (#20098)
This commit is contained in:
parent
1a35a01149
commit
0174de19dd
@ -1002,6 +1002,8 @@
|
||||
"explorer": "Explorer",
|
||||
"export": "Export",
|
||||
"export_as_json": "Export as JSON",
|
||||
"export_database": "Export Database",
|
||||
"export_database_description": "Export the SQLite database",
|
||||
"extension": "Extension",
|
||||
"external": "External",
|
||||
"external_libraries": "External Libraries",
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:drift/drift.dart' as drift_db;
|
||||
import 'package:flutter/material.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/sync_status.provider.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 {
|
||||
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>>(
|
||||
future: loadCounts(),
|
||||
builder: (context, snapshot) {
|
||||
@ -232,6 +298,19 @@ class BetaSyncSettings extends HookConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
_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(
|
||||
title: Text(
|
||||
"reset_sqlite".t(context: context),
|
||||
|
Loading…
x
Reference in New Issue
Block a user