[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 <kode54@gmail.com>
swiftingly
Christopher Snowhill 2022-06-18 18:41:14 -07:00
parent 7cad442b73
commit 8cb46b4f15
5 changed files with 37 additions and 7 deletions

View File

@ -854,7 +854,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
- (NSArray *)addDatabase { - (NSArray *)addDatabase {
SQLiteStore *store = [SQLiteStore sharedStore]; SQLiteStore *store = [SQLiteStore sharedStore];
int64_t count = [store playlistGetCount]; int64_t count = [store playlistGetCountCached];
NSInteger i = 0; NSInteger i = 0;
NSMutableArray *entries = [NSMutableArray arrayWithCapacity:count]; NSMutableArray *entries = [NSMutableArray arrayWithCapacity:count];

View File

@ -42,9 +42,10 @@
- (void)playlistRemoveTracks:(int64_t)index forCount:(int64_t)count progressCall:(void (^)(double progress))callback; - (void)playlistRemoveTracks:(int64_t)index forCount:(int64_t)count progressCall:(void (^)(double progress))callback;
- (void)playlistRemoveTracksAtIndexes:(NSIndexSet *)indexes progressCall:(void (^)(double progress))callback; - (void)playlistRemoveTracksAtIndexes:(NSIndexSet *)indexes progressCall:(void (^)(double progress))callback;
- (PlaylistEntry *)playlistGetItem:(int64_t)index; - (PlaylistEntry *)playlistGetItem:(int64_t)index;
- (int64_t)playlistGetCount;
#endif #endif
- (PlaylistEntry *)playlistGetCachedItem:(int64_t)index; - (PlaylistEntry *)playlistGetCachedItem:(int64_t)index;
- (int64_t)playlistGetCount; - (int64_t)playlistGetCountCached;
#if 0 #if 0
- (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex progressCall:(void (^)(double))callback; - (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex progressCall:(void (^)(double))callback;

View File

@ -734,7 +734,7 @@ static SQLiteStore *g_sharedStore = nil;
for(size_t i = 0; i < count; ++i) { for(size_t i = 0; i < count; ++i) {
PlaylistEntry *pe = [self playlistGetItem:i]; PlaylistEntry *pe = [self playlistGetItem:i];
[databaseMirror addObject:pe]; if(pe) [databaseMirror addObject:pe];
} }
return self; return self;
@ -1445,13 +1445,20 @@ static SQLiteStore *g_sharedStore = nil;
- (PlaylistEntry *_Nonnull)getTrack:(int64_t)trackId { - (PlaylistEntry *_Nonnull)getTrack:(int64_t)trackId {
PlaylistEntry *entry = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:__persistentContainer.viewContext]; 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; return entry;
}
sqlite3_stmt *st = stmt[stmt_select_track_data]; sqlite3_stmt *st = stmt[stmt_select_track_data];
if(sqlite3_reset(st) || if(sqlite3_reset(st) ||
sqlite3_bind_int64(st, select_track_data_in_id, trackId)) { sqlite3_bind_int64(st, select_track_data_in_id, trackId)) {
entry.error = YES;
entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @"");
entry.deLeted = YES;
return entry; return entry;
} }
@ -1459,6 +1466,9 @@ static SQLiteStore *g_sharedStore = nil;
if(rc != SQLITE_ROW && rc != SQLITE_DONE) { if(rc != SQLITE_ROW && rc != SQLITE_DONE) {
sqlite3_reset(st); sqlite3_reset(st);
entry.error = YES;
entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @"");
entry.deLeted = YES;
return entry; return entry;
} }
@ -1529,6 +1539,10 @@ static SQLiteStore *g_sharedStore = nil;
entry.metadataLoaded = !!metadataloaded; entry.metadataLoaded = !!metadataloaded;
entry.dbIndex = trackId; entry.dbIndex = trackId;
} else {
entry.error = YES;
entry.errorMessage = NSLocalizedString(@"ErrorTrackMissing", @"");
entry.deLeted = YES;
} }
sqlite3_reset(st); 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 trackId = sqlite3_column_int64(st, select_playlist_out_track_id);
int64_t entryId = sqlite3_column_int64(st, select_playlist_out_entry_id); int64_t entryId = sqlite3_column_int64(st, select_playlist_out_entry_id);
entry = [self getTrack:trackId]; entry = [self getTrack:trackId];
entry.index = index; if(!entry.deLeted && !entry.error) {
entry.entryId = entryId; entry.index = index;
entry.entryId = entryId;
} else {
[__persistentContainer.viewContext deleteObject:entry];
entry = nil;
}
} }
sqlite3_reset(st); sqlite3_reset(st);
@ -1869,6 +1888,10 @@ static SQLiteStore *g_sharedStore = nil;
return ret; return ret;
} }
- (int64_t)playlistGetCountCached {
return [databaseMirror count];
}
#if 0 #if 0
- (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex progressCall:(void (^)(double))callback { - (void)playlistMoveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex progressCall:(void (^)(double))callback {
__block NSUInteger rangeCount = 0; __block NSUInteger rangeCount = 0;
@ -2042,7 +2065,7 @@ static SQLiteStore *g_sharedStore = nil;
return; return;
} }
int64_t count = [self playlistGetCount]; int64_t count = [self playlistGetCountCached];
if(count != [entries count]) { if(count != [entries count]) {
callback(-1); callback(-1);

View File

@ -59,3 +59,6 @@
"ErrorMetadata" = "Unable to retrieve metadata."; "ErrorMetadata" = "Unable to retrieve metadata.";
"ErrorMessageBadFile" = "Unable to parse metadata for bad file."; "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.";

View File

@ -59,3 +59,6 @@
"ErrorMetadata" = "Unable to retrieve metadata."; "ErrorMetadata" = "Unable to retrieve metadata.";
"ErrorMessageBadFile" = "Unable to parse metadata for bad file."; "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.";