From 3e7e879c9277b70cad8f7cb3269c3eecf1cfb753 Mon Sep 17 00:00:00 2001 From: UnicornsOnLSD <44349936+UnicornsOnLSD@users.noreply.github.com> Date: Fri, 30 Jul 2021 21:05:03 +0100 Subject: [PATCH 1/4] Use support dir instead of documents dir --- hive_flutter/lib/hive_flutter.dart | 2 + hive_flutter/lib/src/hive_extensions.dart | 45 +++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/hive_flutter/lib/hive_flutter.dart b/hive_flutter/lib/hive_flutter.dart index a4b2492e3..20402cf76 100644 --- a/hive_flutter/lib/hive_flutter.dart +++ b/hive_flutter/lib/hive_flutter.dart @@ -1,10 +1,12 @@ library hive_flutter; import 'dart:async'; +import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:hive/hive.dart'; +import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart' if (dart.library.html) 'src/stub/path_provider.dart'; import 'package:path/path.dart' if (dart.library.html) 'src/stub/path.dart' diff --git a/hive_flutter/lib/src/hive_extensions.dart b/hive_flutter/lib/src/hive_extensions.dart index e2693badb..e4e33b4ed 100644 --- a/hive_flutter/lib/src/hive_extensions.dart +++ b/hive_flutter/lib/src/hive_extensions.dart @@ -2,14 +2,53 @@ part of hive_flutter; /// Flutter extensions for Hive. extension HiveX on HiveInterface { - /// Initializes Hive with the path from [getApplicationDocumentsDirectory]. + /// Initializes Hive with the path from [getApplicationSupportDirectory]. /// /// You can provide a [subDir] where the boxes should be stored. Future initFlutter([String? subDir]) async { WidgetsFlutterBinding.ensureInitialized(); if (kIsWeb) return; - var appDir = await getApplicationDocumentsDirectory(); - init(path_helper.join(appDir.path, subDir)); + // Get the directory that Hive uses to stor DB files (support dir + subdir). + final supportDir = await getApplicationSupportDirectory(); + final appDir = path_helper.join(supportDir.path, subDir); + + // If the app dir doesn't exist, create it. This is usually handled later on + // in Hive but the directory needs to exist to copy old DB files over. + if (!await Directory(appDir).exists()) { + await Directory(appDir).create(); + } + + // Get the old location that Hive used to store files. + final documentsDir = await getApplicationDocumentsDirectory(); + final oldLocationDir = + Directory(path_helper.join(documentsDir.path, subDir)); + + // If the old location exists, we start looking for old DB files to copy. + if (await oldLocationDir.exists()) { + // Make an array to store files to copy. + final filesToCopy = []; + + await oldLocationDir.list().forEach((event) { + final extension = path.extension(event.path); + + // If the item is a file and has an extension of .hive/.lock, add it to + // the copy array. + if (extension is File && + (extension == '.hive' || extension == '.lock')) { + filesToCopy.add(event); + } + }); + + // Make copy/delete futures for every file and wait for them + // asynchronously. Files are copied to the new appDir. + await Future.wait(filesToCopy.map( + (e) => File(e.path) + .copy(path_helper.join(appDir, path_helper.basename(e.path))) + .then((value) => File(e.path).delete()), + )); + } + + init(appDir); } } From 88ef50b1634a6d67ab678f4324f412ca9edb677a Mon Sep 17 00:00:00 2001 From: UnicornsOnLSD <44349936+UnicornsOnLSD@users.noreply.github.com> Date: Fri, 30 Jul 2021 21:24:47 +0100 Subject: [PATCH 2/4] Instead of copying all .lock files, copy .lock files with accompanying .hive files --- hive_flutter/lib/src/hive_extensions.dart | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/hive_flutter/lib/src/hive_extensions.dart b/hive_flutter/lib/src/hive_extensions.dart index e4e33b4ed..2beaad9e3 100644 --- a/hive_flutter/lib/src/hive_extensions.dart +++ b/hive_flutter/lib/src/hive_extensions.dart @@ -27,25 +27,28 @@ extension HiveX on HiveInterface { // If the old location exists, we start looking for old DB files to copy. if (await oldLocationDir.exists()) { // Make an array to store files to copy. - final filesToCopy = []; + final filesToCopy = []; await oldLocationDir.list().forEach((event) { final extension = path.extension(event.path); - // If the item is a file and has an extension of .hive/.lock, add it to - // the copy array. - if (extension is File && - (extension == '.hive' || extension == '.lock')) { - filesToCopy.add(event); + // If the item is a file and has an extension of .hive, add it and the + // matching .lock file to the copy array. + if (event is File && extension == '.hive') { + filesToCopy.add(File(event.path)); + + // We do this instead of just copying all .lock files since .lock can + // commonly be used for non-Hive purposes. + filesToCopy.add(File(event.path.replaceAll('.hive', '.lock'))); } }); // Make copy/delete futures for every file and wait for them // asynchronously. Files are copied to the new appDir. await Future.wait(filesToCopy.map( - (e) => File(e.path) + (e) => e .copy(path_helper.join(appDir, path_helper.basename(e.path))) - .then((value) => File(e.path).delete()), + .then((_) => e.delete()), )); } From 250c9a4cb797f755036095c0f2f691c53027c9a6 Mon Sep 17 00:00:00 2001 From: UnicornsOnLSD <44349936+UnicornsOnLSD@users.noreply.github.com> Date: Fri, 30 Jul 2021 21:45:23 +0100 Subject: [PATCH 3/4] Better .lock file picking, remove redundant import --- hive_flutter/lib/hive_flutter.dart | 1 - hive_flutter/lib/src/hive_extensions.dart | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hive_flutter/lib/hive_flutter.dart b/hive_flutter/lib/hive_flutter.dart index 20402cf76..b31adbdef 100644 --- a/hive_flutter/lib/hive_flutter.dart +++ b/hive_flutter/lib/hive_flutter.dart @@ -6,7 +6,6 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:hive/hive.dart'; -import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart' if (dart.library.html) 'src/stub/path_provider.dart'; import 'package:path/path.dart' if (dart.library.html) 'src/stub/path.dart' diff --git a/hive_flutter/lib/src/hive_extensions.dart b/hive_flutter/lib/src/hive_extensions.dart index 2beaad9e3..cbbaac5aa 100644 --- a/hive_flutter/lib/src/hive_extensions.dart +++ b/hive_flutter/lib/src/hive_extensions.dart @@ -30,7 +30,7 @@ extension HiveX on HiveInterface { final filesToCopy = []; await oldLocationDir.list().forEach((event) { - final extension = path.extension(event.path); + final extension = path_helper.extension(event.path); // If the item is a file and has an extension of .hive, add it and the // matching .lock file to the copy array. @@ -39,7 +39,8 @@ extension HiveX on HiveInterface { // We do this instead of just copying all .lock files since .lock can // commonly be used for non-Hive purposes. - filesToCopy.add(File(event.path.replaceAll('.hive', '.lock'))); + filesToCopy + .add(File('${path_helper.withoutExtension(event.path)}.lock')); } }); From b9192b110dfb49e0d4130cb4d23bd3a6d3943b0c Mon Sep 17 00:00:00 2001 From: UnicornsOnLSD <44349936+UnicornsOnLSD@users.noreply.github.com> Date: Fri, 3 Sep 2021 15:23:26 +0100 Subject: [PATCH 4/4] Make using support dir/migrate optional --- hive_flutter/lib/src/hive_extensions.dart | 104 +++++++++++++--------- 1 file changed, 62 insertions(+), 42 deletions(-) diff --git a/hive_flutter/lib/src/hive_extensions.dart b/hive_flutter/lib/src/hive_extensions.dart index cbbaac5aa..c73741d45 100644 --- a/hive_flutter/lib/src/hive_extensions.dart +++ b/hive_flutter/lib/src/hive_extensions.dart @@ -2,55 +2,75 @@ part of hive_flutter; /// Flutter extensions for Hive. extension HiveX on HiveInterface { - /// Initializes Hive with the path from [getApplicationSupportDirectory]. + /// Initializes Hive with the path from either + /// [getApplicationDocumentsDirectory] (default) or + /// [getApplicationSupportDirectory] ([useSupportDir] = true). /// - /// You can provide a [subDir] where the boxes should be stored. - Future initFlutter([String? subDir]) async { + /// You can provide a [subDir] where the boxes should be stored. if + /// [migrateFromDocuments] is set to true, Boxes in (documents dir + subdir) + /// will be copied over to (support dir + subdir) + /// + /// [useSupportDir] cannot be false when [migrateFromDocuments] is true, and + /// vice versa. + Future initFlutter({ + bool useSupportDir = false, + bool migrateFromDocuments = false, + String? subDir, + }) async { + // We don't want the developer to migrate from documents and then try to + // init Hive with the documents dir. + assert(useSupportDir == false && migrateFromDocuments == true); + WidgetsFlutterBinding.ensureInitialized(); if (kIsWeb) return; - // Get the directory that Hive uses to stor DB files (support dir + subdir). - final supportDir = await getApplicationSupportDirectory(); + // Get the directory that Hive uses to stor DB files (dir + subdir). + final supportDir = useSupportDir + ? await getApplicationSupportDirectory() + : await getApplicationDocumentsDirectory(); + final appDir = path_helper.join(supportDir.path, subDir); - // If the app dir doesn't exist, create it. This is usually handled later on - // in Hive but the directory needs to exist to copy old DB files over. - if (!await Directory(appDir).exists()) { - await Directory(appDir).create(); - } + if (migrateFromDocuments) { + // If the app dir doesn't exist, create it. This is usually handled later + // on in Hive but the directory needs to exist to copy old DB files over. + if (!await Directory(appDir).exists()) { + await Directory(appDir).create(); + } + + // Get the old location that Hive used to store files. + final documentsDir = await getApplicationDocumentsDirectory(); + final oldLocationDir = + Directory(path_helper.join(documentsDir.path, subDir)); + + // If the old location exists, we start looking for old DB files to copy. + if (await oldLocationDir.exists()) { + // Make an array to store files to copy. + final filesToCopy = []; + + await oldLocationDir.list().forEach((event) { + final extension = path_helper.extension(event.path); + + // If the item is a file and has an extension of .hive, add it and the + // matching .lock file to the copy array. + if (event is File && extension == '.hive') { + filesToCopy.add(File(event.path)); + + // We do this instead of just copying all .lock files since .lock + // can commonly be used for non-Hive purposes. + filesToCopy + .add(File('${path_helper.withoutExtension(event.path)}.lock')); + } + }); - // Get the old location that Hive used to store files. - final documentsDir = await getApplicationDocumentsDirectory(); - final oldLocationDir = - Directory(path_helper.join(documentsDir.path, subDir)); - - // If the old location exists, we start looking for old DB files to copy. - if (await oldLocationDir.exists()) { - // Make an array to store files to copy. - final filesToCopy = []; - - await oldLocationDir.list().forEach((event) { - final extension = path_helper.extension(event.path); - - // If the item is a file and has an extension of .hive, add it and the - // matching .lock file to the copy array. - if (event is File && extension == '.hive') { - filesToCopy.add(File(event.path)); - - // We do this instead of just copying all .lock files since .lock can - // commonly be used for non-Hive purposes. - filesToCopy - .add(File('${path_helper.withoutExtension(event.path)}.lock')); - } - }); - - // Make copy/delete futures for every file and wait for them - // asynchronously. Files are copied to the new appDir. - await Future.wait(filesToCopy.map( - (e) => e - .copy(path_helper.join(appDir, path_helper.basename(e.path))) - .then((_) => e.delete()), - )); + // Make copy/delete futures for every file and wait for them + // asynchronously. Files are copied to the new appDir. + await Future.wait(filesToCopy.map( + (e) => e + .copy(path_helper.join(appDir, path_helper.basename(e.path))) + .then((_) => e.delete()), + )); + } } init(appDir);