diff options
Diffstat (limited to 'browser/components/backup/resources/PlacesBackupResource.sys.mjs')
-rw-r--r-- | browser/components/backup/resources/PlacesBackupResource.sys.mjs | 69 |
1 files changed, 54 insertions, 15 deletions
diff --git a/browser/components/backup/resources/PlacesBackupResource.sys.mjs b/browser/components/backup/resources/PlacesBackupResource.sys.mjs index 1955406f51..3a9433e67c 100644 --- a/browser/components/backup/resources/PlacesBackupResource.sys.mjs +++ b/browser/components/backup/resources/PlacesBackupResource.sys.mjs @@ -10,7 +10,6 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { BookmarkJSONUtils: "resource://gre/modules/BookmarkJSONUtils.sys.mjs", PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", - Sqlite: "resource://gre/modules/Sqlite.sys.mjs", }); XPCOMUtils.defineLazyPreferenceGetter( @@ -26,6 +25,8 @@ XPCOMUtils.defineLazyPreferenceGetter( false ); +const BOOKMARKS_BACKUP_FILENAME = "bookmarks.jsonlz4"; + /** * Class representing Places database related files within a user profile. */ @@ -38,8 +39,11 @@ export class PlacesBackupResource extends BackupResource { return false; } + static get priority() { + return 1; + } + async backup(stagingPath, profilePath = PathUtils.profileDir) { - const sqliteDatabases = ["places.sqlite", "favicons.sqlite"]; let canBackupHistory = !lazy.PrivateBrowsingUtils.permanentPrivateBrowsing && !lazy.isSanitizeOnShutdownEnabled && @@ -52,7 +56,7 @@ export class PlacesBackupResource extends BackupResource { if (!canBackupHistory) { let bookmarksBackupFile = PathUtils.join( stagingPath, - "bookmarks.jsonlz4" + BOOKMARKS_BACKUP_FILENAME ); await lazy.BookmarkJSONUtils.exportToFile(bookmarksBackupFile, { compress: true, @@ -60,25 +64,60 @@ export class PlacesBackupResource extends BackupResource { return { bookmarksOnly: true }; } - for (let fileName of sqliteDatabases) { - let sourcePath = PathUtils.join(profilePath, fileName); - let destPath = PathUtils.join(stagingPath, fileName); - let connection; + // These are copied in parallel because they're attached[1], and we don't + // want them to get out of sync with one another. + // + // [1]: https://www.sqlite.org/lang_attach.html + await Promise.all([ + BackupResource.copySqliteDatabases(profilePath, stagingPath, [ + "places.sqlite", + ]), + BackupResource.copySqliteDatabases(profilePath, stagingPath, [ + "favicons.sqlite", + ]), + ]); + + return null; + } - try { - connection = await lazy.Sqlite.openConnection({ - path: sourcePath, - readOnly: true, - }); + async recover(manifestEntry, recoveryPath, destProfilePath) { + if (!manifestEntry) { + const simpleCopyFiles = ["places.sqlite", "favicons.sqlite"]; + await BackupResource.copyFiles( + recoveryPath, + destProfilePath, + simpleCopyFiles + ); + } else { + const { bookmarksOnly } = manifestEntry; - await connection.backup(destPath); - } finally { - await connection.close(); + /** + * If the recovery file only has bookmarks backed up, pass the file path to postRecovery() + * so that we can import all bookmarks into the new profile once it's been launched and restored. + */ + if (bookmarksOnly) { + let bookmarksBackupPath = PathUtils.join( + recoveryPath, + BOOKMARKS_BACKUP_FILENAME + ); + return { bookmarksBackupPath }; } } + return null; } + async postRecovery(postRecoveryEntry) { + if (postRecoveryEntry?.bookmarksBackupPath) { + await lazy.BookmarkJSONUtils.importFromFile( + postRecoveryEntry.bookmarksBackupPath, + { + replace: true, + } + ); + } + } + async measure(profilePath = PathUtils.profileDir) { let placesDBPath = PathUtils.join(profilePath, "places.sqlite"); let faviconsDBPath = PathUtils.join(profilePath, "favicons.sqlite"); |