diff --git a/ios/Classes/DBManager.m b/ios/Classes/DBManager.m index 3932d239..92e0ed50 100644 --- a/ios/Classes/DBManager.m +++ b/ios/Classes/DBManager.m @@ -117,86 +117,86 @@ -(void)runQuery:(const char *)query isQueryExecutable:(BOOL)queryExecutable{ } return; } - if(openDatabaseResult == SQLITE_OK) { - if (debug) { - NSLog(@"open DB successfully"); - } - - // Declare a sqlite3_stmt object in which will be stored the query after having been compiled into a SQLite statement. - sqlite3_stmt *compiledStatement; - - // Load all data from database to memory. - int prepareStatementResult = sqlite3_prepare_v2(sqlite3Database, query, -1, &compiledStatement, NULL); - if(prepareStatementResult == SQLITE_OK) { - // Check if the query is non-executable. - if (!queryExecutable){ - // In this case data must be loaded from the database. + + if (debug) { + NSLog(@"open DB successfully"); + } + + // Declare a sqlite3_stmt object in which will be stored the query after having been compiled into a SQLite statement. + sqlite3_stmt *compiledStatement; + + // Load all data from database to memory. + int prepareStatementResult = sqlite3_prepare_v2(sqlite3Database, query, -1, &compiledStatement, NULL); + if(prepareStatementResult == SQLITE_OK) { + // Check if the query is non-executable. + if (!queryExecutable){ + // In this case data must be loaded from the database. + + // Declare an array to keep the data for each fetched row. + NSMutableArray *arrDataRow; + + // Loop through the results and add them to the results array row by row. + while(sqlite3_step(compiledStatement) == SQLITE_ROW) { + // Initialize the mutable array that will contain the data of a fetched row. + arrDataRow = [[NSMutableArray alloc] init]; - // Declare an array to keep the data for each fetched row. - NSMutableArray *arrDataRow; + // Get the total number of columns. + int totalColumns = sqlite3_column_count(compiledStatement); - // Loop through the results and add them to the results array row by row. - while(sqlite3_step(compiledStatement) == SQLITE_ROW) { - // Initialize the mutable array that will contain the data of a fetched row. - arrDataRow = [[NSMutableArray alloc] init]; - - // Get the total number of columns. - int totalColumns = sqlite3_column_count(compiledStatement); + // Go through all columns and fetch each column data. + for (int i=0; i 0) { - [self.arrResults addObject:arrDataRow]; + // Keep the current column name. + if (self.arrColumnNames.count != totalColumns) { + dbDataAsChars = (char *)sqlite3_column_name(compiledStatement, i); + [self.arrColumnNames addObject:[NSString stringWithUTF8String:dbDataAsChars]]; } } - } - else { - // This is the case of an executable query (insert, update, ...). - // Execute the query. - int executeQueryResults = sqlite3_step(compiledStatement); - if (executeQueryResults == SQLITE_DONE) { - // Keep the affected rows. - self.affectedRows = sqlite3_changes(sqlite3Database); - - // Keep the last inserted row ID. - self.lastInsertedRowID = sqlite3_last_insert_rowid(sqlite3Database); - } - else { - // If could not execute the query show the error message on the debugger. - if (debug) { - NSLog(@"DB Error: %s", sqlite3_errmsg(sqlite3Database)); - } + // Store each fetched data row in the results array, but first check if there is actually data. + if (arrDataRow.count > 0) { + [self.arrResults addObject:arrDataRow]; } } } else { - // In the database cannot be opened then show the error message on the debugger. - if (debug) { - NSLog(@"%s", sqlite3_errmsg(sqlite3Database)); + // This is the case of an executable query (insert, update, ...). + + // Execute the query. + int executeQueryResults = sqlite3_step(compiledStatement); + if (executeQueryResults == SQLITE_DONE) { + // Keep the affected rows. + self.affectedRows = sqlite3_changes(sqlite3Database); + + // Keep the last inserted row ID. + self.lastInsertedRowID = sqlite3_last_insert_rowid(sqlite3Database); + } + else { + // If could not execute the query show the error message on the debugger. + if (debug) { + NSLog(@"DB Error: %s", sqlite3_errmsg(sqlite3Database)); + } } } - - // Release the compiled statement from memory. - sqlite3_finalize(compiledStatement); } + else { + // In the database cannot be opened then show the error message on the debugger. + if (debug) { + NSLog(@"%s", sqlite3_errmsg(sqlite3Database)); + } + } + + // Release the compiled statement from memory. + sqlite3_finalize(compiledStatement); + // Close the database. sqlite3_close(sqlite3Database); diff --git a/ios/Classes/FlutterDownloaderPlugin.m b/ios/Classes/FlutterDownloaderPlugin.m index e3385b37..3446c52f 100644 --- a/ios/Classes/FlutterDownloaderPlugin.m +++ b/ios/Classes/FlutterDownloaderPlugin.m @@ -39,11 +39,6 @@ @interface FlutterDownloaderPlugin() *_runningTaskById = nil; - - -@synthesize databaseQueue; +static dispatch_queue_t databaseQueue; +static void *isOnDatabaseQueueKey; - (instancetype)init:(NSObject *)registrar; { @@ -92,7 +86,15 @@ - (instancetype)init:(NSObject *)registrar; if (debug) { NSLog(@"database path: %@", dbPath); } - databaseQueue = dispatch_queue_create("vn.hunghd.flutter_downloader", 0); + + if (databaseQueue == nil) { + databaseQueue = dispatch_queue_create("vn.hunghd.flutter_downloader", 0); + + isOnDatabaseQueueKey = &isOnDatabaseQueueKey; + void *nonNullUnusedPointer = (__bridge void *)(self.class); + dispatch_queue_set_specific(databaseQueue, isOnDatabaseQueueKey, nonNullUnusedPointer, NULL); + } + _dbManager = [[DBManager alloc] initWithDatabaseFilePath:dbPath]; if (_runningTaskById == nil) { @@ -298,11 +300,13 @@ - (void)sendUpdateProgressForTaskId: (NSString*)taskId inStatus: (NSNumber*) sta } - (void)executeInDatabaseQueueForTask:(void (^)(void))task { - __typeof__(self) __weak weakSelf = self; - dispatch_sync(databaseQueue, ^{ - if (weakSelf.isDatabaseQueueTerminated) return; + if (dispatch_get_specific(isOnDatabaseQueueKey)) { if (task) task(); - }); + } else { + dispatch_sync(databaseQueue, ^{ + if (task) task(); + }); + } } - (BOOL)openDocumentWithURL:(NSURL*)url { @@ -539,7 +543,14 @@ - (NSDictionary*)loadTaskWithId:(NSString*)taskId return [_runningTaskById objectForKey:taskId]; } else { NSString *query = [NSString stringWithFormat:@"SELECT * FROM task WHERE task_id = \"%@\" ORDER BY id DESC LIMIT 1", taskId]; - NSArray *records = [[NSArray alloc] initWithArray:[_dbManager loadDataFromDB:query]]; + + __block NSArray *records; + + __typeof__(_dbManager) __weak weakDbManager = _dbManager; + [self executeInDatabaseQueueForTask:^{ + records = [[NSArray alloc] initWithArray:[weakDbManager loadDataFromDB:query]]; + }]; + if (debug) { NSLog(@"Load task successfully"); }