@@ -493,53 +493,62 @@ - (void)openDatabase {
493493 dispatch_async (_databaseOperationQueue, ^{
494494 NSFileManager *fileManager = [NSFileManager defaultManager ];
495495 NSString *path = [self pathForDatabase ];
496-
497- BOOL didOpenDatabase = YES ;
498- if (![fileManager fileExistsAtPath: path]) {
499- // We've to separate between different versions here because of backward compatibility issues.
500- int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
496+ BOOL fileExists = [fileManager fileExistsAtPath: path];
497+
498+ // Ensure the directory exists before trying to create the database if the file doesn't exist.
499+ if (!fileExists) {
500+ NSString *directory = [path stringByDeletingLastPathComponent ];
501+ if (![fileManager fileExistsAtPath: directory]) {
502+ NSError *error;
503+ if (![fileManager createDirectoryAtPath: directory
504+ withIntermediateDirectories: YES
505+ attributes: nil
506+ error: &error]) {
507+ NSString *errorMessage = [NSString
508+ stringWithFormat: @" Could not create RMQ database directory at path %@ , error: %@ " ,
509+ directory, error];
510+ FIRMessagingLoggerError (kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase ,
511+ @" %@ " , errorMessage);
512+ NSAssert (NO , errorMessage);
513+ return ;
514+ }
515+ }
516+ }
517+ int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
501518#ifdef SQLITE_OPEN_FILEPROTECTION_NONE
502- flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
519+ flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
503520#endif
504- int result = sqlite3_open_v2 ([path UTF8String ], &self -> _database, flags, NULL );
505- if (result != SQLITE_OK) {
506- NSString *errorString = FIRMessagingStringFromSQLiteResult (result);
507- NSString *errorMessage = [NSString
508- stringWithFormat: @" Could not open existing RMQ database at path %@ , error: %@ " , path,
509- errorString];
510- FIRMessagingLoggerError (kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase ,
511- @" %@ " , errorMessage);
512- NSAssert (NO , errorMessage);
513- return ;
521+ int result = sqlite3_open_v2 ([path UTF8String ], &self -> _database, flags, NULL );
522+ if (result != SQLITE_OK) {
523+ NSString *errorString = FIRMessagingStringFromSQLiteResult (result);
524+ NSString *errorMessage =
525+ [NSString stringWithFormat: @" Could not open or create RMQ database at path %@ , error: %@ " ,
526+ path, errorString];
527+ FIRMessagingLoggerError (kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase ,
528+ @" %@ " , errorMessage);
529+
530+ // If the file existed, it might be corrupt. Let's remove it and fail.
531+ if (fileExists) {
532+ // This is synchronous, but it's on the database queue, so it's safe.
533+ [[NSFileManager defaultManager ] removeItemAtPath: path error: nil ];
514534 }
535+ NSAssert (NO , errorMessage);
536+ return ;
537+ }
538+
539+ if (!fileExists) {
540+ // New database, create tables.
515541 [self createTableWithName: kTableOutgoingRmqMessages command: kCreateTableOutgoingRmqMessages ];
516542
517543 [self createTableWithName: kTableLastRmqId command: kCreateTableLastRmqId ];
518544 [self createTableWithName: kTableS2DRmqIds command: kCreateTableS2DRmqIds ];
519545 } else {
520- // Calling sqlite3_open should create the database, since the file doesn't exist.
521- int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
522- #ifdef SQLITE_OPEN_FILEPROTECTION_NONE
523- flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
524- #endif
525- int result = sqlite3_open_v2 ([path UTF8String ], &self -> _database, flags, NULL );
526- if (result != SQLITE_OK) {
527- NSString *errorString = FIRMessagingStringFromSQLiteResult (result);
528- NSString *errorMessage =
529- [NSString stringWithFormat: @" Could not create RMQ database at path %@ , error: %@ " , path,
530- errorString];
531- FIRMessagingLoggerError (kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase ,
532- @" %@ " , errorMessage);
533- NSAssert (NO , errorMessage);
534- didOpenDatabase = NO ;
535- } else {
536- [self updateDBWithStringRmqID ];
537- }
546+ // Existing database, update schema if needed.
547+ [self updateDBWithStringRmqID ];
538548 }
539549
540- if (didOpenDatabase) {
541- [self createTableWithName: kTableSyncMessages command: kCreateTableSyncMessages ];
542- }
550+ // This table should exist in both new and old databases.
551+ [self createTableWithName: kTableSyncMessages command: kCreateTableSyncMessages ];
543552 });
544553}
545554
0 commit comments