Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions lib/common/preferences/preference_key.dart
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ enum PreferenceKey<T extends Object> {
/// Returns the value of this preference if set, or its default value otherwise.
T get preferenceOrDefault => PreferencesWrapper().get<T>(this) ?? defaultValue;

/// Returns the value of this securely stored preference if set, or [null] otherwise.
T? get preferenceSecure => PreferencesWrapper().get<T>(this);

/// Returns the value of this securely stored preference if set, or its default value otherwise.
Future<String> get preferenceOrDefaultSecure async =>
await PreferencesWrapper().getSecure(this) ?? defaultValue as String;
Expand Down
2 changes: 1 addition & 1 deletion lib/l10n/translations/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@
"@settings_auto_export_frequency": {
"description": "Title of the settings tile to choose the frequency of the automatic exports."
},
"settings_auto_export_frequency_value": "Every {frequency, select, 1{day} 7{week} 14{2 weeks} 30{month} other{}}",
"settings_auto_export_frequency_value": "Every {frequency, select, 1{day} 3{3 days} 7{week} 14{2 weeks} 30{month} other{}}",
"@settings_auto_export_frequency_value": {
"description": "Frequency of the automatic exports.",
"placeholders": {
Expand Down
4 changes: 3 additions & 1 deletion lib/models/note/note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ sealed class Note implements Comparable<Note> {
case SortMethod.editedDate:
return sortAscending ? editedTime.compareTo(other.editedTime) : other.editedTime.compareTo(editedTime);
case SortMethod.title:
return sortAscending ? title.compareTo(other.title) : other.title.compareTo(title);
final titleComparison = title.toLowerCase().compareTo(other.title.toLowerCase());

return sortAscending ? titleComparison : -titleComparison;
default:
throw Exception('The sort method is not valid: $sortMethod');
}
Expand Down
46 changes: 31 additions & 15 deletions lib/services/migration/migration_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import 'package:isar_community/isar.dart';
import '../../common/constants/constants.dart';
import '../../common/preferences/preference_key.dart';
import '../../models/deprecated/note.dart';
import '../../models/label/label.dart';
import '../../models/note/note.dart';
import '../database_service.dart';
import '../notes/notes_service.dart';

/// Database migration service.
class MigrationService {
final _databaseService = DatabaseService();
final _notesService = NotesService();

/// Migrates the database to the latest version if needed.
Future<void> migrateIfNeeded() async {
Expand All @@ -30,13 +29,12 @@ class MigrationService {
/// Moves all legacy notes from the legacy `notes` collection to the new `richTextNotes` collection
/// to allow adding different types of notes.
Future<void> _migrateToV2() async {
final database = _databaseService.database;

// Get the notes and their labels
final notes = await _databaseService.database.notes.where().findAll();
final notes = await database.notes.where().findAll();
final labels = notes.map((note) => note.labels.toList()).toList();

// Remove the notes
await _databaseService.database.notes.clear();

// Migrate the notes
final migratedNotes = notes
.map(
Expand All @@ -53,9 +51,12 @@ class MigrationService {
)
.toList();

// Add the migrated notes to the new collection with their labels
await _notesService.putAll(migratedNotes);
await _notesService.putAllLabels(migratedNotes, labels);
// Replace the notes by the migrated ones with their labels, all at once so that a failure loses nothing
await database.writeTxn(() async {
await database.notes.clear();
await database.richTextNotes.putAll(migratedNotes);
await _putLabels(migratedNotes, labels);
});

// Update the database version
await PreferenceKey.databaseVersion.set(2);
Expand All @@ -67,11 +68,12 @@ class MigrationService {
///
/// Sets the new `id`, `archived` and `deletedTime` fields of each rich text note.
Future<void> _migrateToV3() async {
// Get the rich text notes
final richTextNotes = await _databaseService.database.richTextNotes.where().findAll();
final database = _databaseService.database;

// Remove the notes with the old IDs
await _notesService.deleteAll(richTextNotes);
// Get the rich text notes, their labels and their old IDs
final richTextNotes = await database.richTextNotes.where().findAll();
final labels = richTextNotes.map((note) => note.labels.toList()).toList();
final oldIds = richTextNotes.map((note) => note.isarId).toList();

// Migrate the notes
final migratedNotes = richTextNotes
Expand All @@ -83,12 +85,26 @@ class MigrationService {
)
.toList();

// Put back the migrated notes with the right IDs
await _notesService.putAll(migratedNotes);
// Replace the notes with the old IDs by the migrated ones with their labels, which are linked to the IDs,
// all at once so that a failure loses nothing
await database.writeTxn(() async {
await database.richTextNotes.deleteAll(oldIds);
await database.richTextNotes.putAll(migratedNotes);
await _putLabels(migratedNotes, labels);
});

// Update the database version
await PreferenceKey.databaseVersion.set(3);

logger.i('Migrated the database from version 2 to version 3');
}

/// Links each of the [notes] to its [labels], inside a write transaction.
Future<void> _putLabels(List<RichTextNote> notes, List<List<Label>> labels) async {
for (var i = 0; i < notes.length; i++) {
await notes[i].labels.reset();
notes[i].labels.addAll(labels[i]);
await notes[i].labels.save();
}
}
}
19 changes: 0 additions & 19 deletions lib/services/notes/notes_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -242,25 +242,6 @@ class NotesService {
});
}

/// Updates the [notes] with their corresponding [notesLabels] in the database.
Future<void> putAllLabels(List<Note> notes, List<List<Label>> notesLabels) async {
assert(
notes.length == notesLabels.length,
'The list of labels (${notesLabels.length} items) should be the same length as the list of notes (${notes.length} notes)',
);

await _database.writeTxn(() async {
for (var i = 0; i < notes.length; i++) {
final note = notes[i];
final labels = notesLabels[i];

await note.labels.reset();
note.labels.addAll(labels);
await note.labels.save();
}
});
}

/// Imports the [labels] and the [notes] in a single transaction, so that a failure leaves the database untouched.
///
/// Only the labels whose name is not in the database yet are added. Each note is linked to the labels
Expand Down
Loading