From 8cb46b4f15c1ac4bc61c6a29438a26f5906b6975 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sat, 18 Jun 2022 18:41:14 -0700 Subject: [PATCH] [Legacy SQLite Store] Handle errors with database Handle missing track items in the databse more gracefully, by deleting the track entries before passing them on to the caller, so problems do not occur later. Signed-off-by: Christopher Snowhill --- Playlist/PlaylistLoader.m | 2 +- Utils/SQLiteStore.h | 3 ++- Utils/SQLiteStore.m | 33 ++++++++++++++++++++++++++++----- en.lproj/Localizable.strings | 3 +++ es.lproj/Localizable.strings | 3 +++ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Playlist/PlaylistLoader.m b/Playlist/PlaylistLoader.m index f2b24c164..bda03494b 100644 --- a/Playlist/PlaylistLoader.m +++ b/Playlist/PlaylistLoader.m @@ -854,7 +854,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc - (NSArray *)addDatabase { SQLiteStore *store = [SQLiteStore sharedStore]; - int64_t count = [store playlistGetCount]; + int64_t count = [store playlistGetCountCached]; NSInteger i = 0; NSMutableArray *entries = [NSMutableArray arrayWithCapacity:count]; diff --git a/Utils/SQLiteStore.h b/Utils/SQLiteStore.h index 4659d81c2..97adb48e2 100644 --- a/Utils/SQLiteStore.h +++ b/Utils/SQLiteStore.h @@ -42,9 +42,10 @@ - (void)playlistRemoveTracks:(int64_t)index forCount:(int64_t)count progressCall:(void (^)(double progress))callback; - (void)playlistRemoveTracksAtIndexes:(NSIndexSet *)indexes progressCall:(void (^)(double progress))callback; - (PlaylistEntry *)playlistGetItem:(int64_t)index; +- (int64_t)playlistGetCount; #endif - (PlaylistEntry *)playlistGetCachedItem:(int64_t)index; -- (int64_t)playlistGetCount; +- (int64_t)playlistGetCountCached; #if 0 - (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex progressCall:(void (^)(double))callback; diff --git a/Utils/SQLiteStore.m b/Utils/SQLiteStore.m index 17381c62e..70234d146 100644 --- a/Utils/SQLiteStore.m +++ b/Utils/SQLiteStore.m @@ -734,7 +734,7 @@ static SQLiteStore *g_sharedStore = nil; for(size_t i = 0; i < count; ++i) { PlaylistEntry *pe = [self playlistGetItem:i]; - [databaseMirror addObject:pe]; + if(pe) [databaseMirror addObject:pe]; } return self; @@ -1445,13 +1445,20 @@ static SQLiteStore *g_sharedStore = nil; - (PlaylistEntry *_Nonnull)getTrack:(int64_t)trackId { PlaylistEntry *entry = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:__persistentContainer.viewContext]; - if(trackId < 0) + if(trackId < 0) { + entry.error = YES; + entry.errorMessage = NSLocalizedString(@"ErrorInvalidTrackId", @""); + entry.deLeted = YES; return entry; + } sqlite3_stmt *st = stmt[stmt_select_track_data]; if(sqlite3_reset(st) || sqlite3_bind_int64(st, select_track_data_in_id, trackId)) { + entry.error = YES; + entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @""); + entry.deLeted = YES; return entry; } @@ -1459,6 +1466,9 @@ static SQLiteStore *g_sharedStore = nil; if(rc != SQLITE_ROW && rc != SQLITE_DONE) { sqlite3_reset(st); + entry.error = YES; + entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @""); + entry.deLeted = YES; return entry; } @@ -1529,6 +1539,10 @@ static SQLiteStore *g_sharedStore = nil; entry.metadataLoaded = !!metadataloaded; entry.dbIndex = trackId; + } else { + entry.error = YES; + entry.errorMessage = NSLocalizedString(@"ErrorTrackMissing", @""); + entry.deLeted = YES; } sqlite3_reset(st); @@ -1845,8 +1859,13 @@ static SQLiteStore *g_sharedStore = nil; int64_t trackId = sqlite3_column_int64(st, select_playlist_out_track_id); int64_t entryId = sqlite3_column_int64(st, select_playlist_out_entry_id); entry = [self getTrack:trackId]; - entry.index = index; - entry.entryId = entryId; + if(!entry.deLeted && !entry.error) { + entry.index = index; + entry.entryId = entryId; + } else { + [__persistentContainer.viewContext deleteObject:entry]; + entry = nil; + } } sqlite3_reset(st); @@ -1869,6 +1888,10 @@ static SQLiteStore *g_sharedStore = nil; return ret; } +- (int64_t)playlistGetCountCached { + return [databaseMirror count]; +} + #if 0 - (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex progressCall:(void (^)(double))callback { __block NSUInteger rangeCount = 0; @@ -2042,7 +2065,7 @@ static SQLiteStore *g_sharedStore = nil; return; } - int64_t count = [self playlistGetCount]; + int64_t count = [self playlistGetCountCached]; if(count != [entries count]) { callback(-1); diff --git a/en.lproj/Localizable.strings b/en.lproj/Localizable.strings index 16f4c854f..695e4a13e 100644 --- a/en.lproj/Localizable.strings +++ b/en.lproj/Localizable.strings @@ -59,3 +59,6 @@ "ErrorMetadata" = "Unable to retrieve metadata."; "ErrorMessageBadFile" = "Unable to parse metadata for bad file."; +"ErrorInvalidTrackId" = "Invalid track ID sent to SQLite request."; +"ErrorSqliteProblem" = "General problem accessing track from SQLite database."; +"ErrorTrackMissing" = "Track entry is missing from SQLite database."; diff --git a/es.lproj/Localizable.strings b/es.lproj/Localizable.strings index 16f4c854f..695e4a13e 100644 --- a/es.lproj/Localizable.strings +++ b/es.lproj/Localizable.strings @@ -59,3 +59,6 @@ "ErrorMetadata" = "Unable to retrieve metadata."; "ErrorMessageBadFile" = "Unable to parse metadata for bad file."; +"ErrorInvalidTrackId" = "Invalid track ID sent to SQLite request."; +"ErrorSqliteProblem" = "General problem accessing track from SQLite database."; +"ErrorTrackMissing" = "Track entry is missing from SQLite database.";