@@ -38,16 +38,16 @@ static BOOL SEGAddSkipBackupAttributeToItemAtPath(NSString *filePathString) {
3838 NSError *error = nil ;
3939 BOOL success = [URL setResourceValue: @YES forKey: NSURLIsExcludedFromBackupKey error: &error];
4040 if (!success) {
41- // TODO(dmandar): log error.
42- NSLog ( @" Error excluding %@ from backup %@ . " , [URL lastPathComponent ], error);
41+ FIRLogError ( kFIRLoggerSegmentation , @" I-SEG000001 " , @" Error excluding %@ from backup %@ . " ,
42+ [URL lastPathComponent ], error);
4343 }
4444 return success;
4545}
4646
4747static BOOL SEGCreateFilePathIfNotExist (NSString *filePath) {
48- if (!filePath || !filePath .length ) {
49- // TODO(dmandar) log error.
50- NSLog ( @" Failed to create subdirectory for an empty file path." );
48+ if (!filePath.length ) {
49+ FIRLogError ( kFIRLoggerSegmentation , @" I-SEG000002 " ,
50+ @" Failed to create subdirectory for an empty file path." );
5151 return NO ;
5252 }
5353 NSFileManager *fileManager = [NSFileManager defaultManager ];
@@ -58,23 +58,20 @@ static BOOL SEGCreateFilePathIfNotExist(NSString *filePath) {
5858 attributes: nil
5959 error: &error];
6060 if (error) {
61- // TODO(dmandar) log error.
62- NSLog ( @" Failed to create subdirectory for database file: %@ ." , error);
61+ FIRLogError ( kFIRLoggerSegmentation , @" I-SEG000003 " ,
62+ @" Failed to create subdirectory for database file: %@ ." , error);
6363 return NO ;
6464 }
6565 }
6666 return YES ;
6767}
6868
69- @interface SEGDatabaseManager () {
69+ @implementation SEGDatabaseManager {
7070 // / Database storing all the config information.
7171 sqlite3 *_database;
7272 // / Serial queue for database read/write operations.
7373 dispatch_queue_t _databaseOperationQueue;
7474}
75- @end
76-
77- @implementation SEGDatabaseManager
7875
7976+ (instancetype )sharedInstance {
8077 static dispatch_once_t onceToken;
@@ -97,41 +94,35 @@ - (instancetype)init {
9794#pragma mark - Public Methods
9895
9996- (void )loadMainTableWithCompletion : (SEGRequestCompletion)completionHandler {
100- __weak SEGDatabaseManager *weakSelf = self;
10197 dispatch_async (_databaseOperationQueue, ^{
102- SEGDatabaseManager *strongSelf = weakSelf;
103- if (!strongSelf) {
104- completionHandler (NO , @{@" Database Error" : @" Internal database error" });
105- }
106-
10798 // Read the database into memory.
10899 NSDictionary <NSString *, NSDictionary <NSString *, NSString *> *> *associations =
109100 [self loadMainTable ];
110- completionHandler (YES , associations);
101+ if (associations != nil ) {
102+ completionHandler (YES , associations);
103+ } else {
104+ FIRLogError (kFIRLoggerSegmentation , @" I-SEG000004" , @" Failed to load main table." );
105+ completionHandler (NO , @{});
106+ }
111107 });
112108 return ;
113109}
114110
115111- (void )createOrOpenDatabaseWithCompletion : (SEGRequestCompletion)completionHandler {
116- __weak SEGDatabaseManager *weakSelf = self;
117112 dispatch_async (_databaseOperationQueue, ^{
118- SEGDatabaseManager *strongSelf = weakSelf;
119- if (!strongSelf) {
120- completionHandler (NO , @{@" ErrorDescription" : @" Internal database error" });
121- }
122113 NSString *dbPath = [SEGDatabaseManager pathForSegmentationDatabase ];
123- // TODO(dmandar) log.
124- NSLog ( @" Loading segmentation database at path %@ " , dbPath);
114+ FIRLogDebug ( kFIRLoggerSegmentation , @" I-SEG000005 " , @" Loading segmentation database at path %@ " ,
115+ dbPath);
125116 const char *databasePath = dbPath.UTF8String ;
126117 // Create or open database path.
127118 if (!SEGCreateFilePathIfNotExist (dbPath)) {
128- completionHandler (NO , @{@" ErrorDescription " : @" Could not create database file at path" });
119+ completionHandler (NO , @{kSEGErrorDescription : @" Could not create database file at path" });
129120 }
130121 int flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FILEPROTECTION_COMPLETE |
131122 SQLITE_OPEN_FULLMUTEX;
132- if (sqlite3_open_v2 (databasePath, &strongSelf ->_database , flags, NULL ) == SQLITE_OK) {
123+ if (sqlite3_open_v2 (databasePath, &self ->_database , flags, NULL ) == SQLITE_OK) {
133124 // Create table if does not exist already.
134- if ([strongSelf createTableSchema ]) {
125+ if ([self createTableSchema ]) {
135126 // DB file created or already exists.
136127 // Exclude the app data used from iCloud backup.
137128 SEGAddSkipBackupAttributeToItemAtPath (dbPath);
@@ -142,42 +133,44 @@ - (void)createOrOpenDatabaseWithCompletion:(SEGRequestCompletion)completionHandl
142133
143134 } else {
144135 // Remove database before fail.
145- [strongSelf removeDatabase: dbPath];
146- FIRLogError (kFIRLoggerSegmentation , @" I-SEG000010 " , @" Failed to create table." );
136+ [self removeDatabase: dbPath];
137+ FIRLogError (kFIRLoggerSegmentation , @" I-SEG00006 " , @" Failed to create table." );
147138 // Create a new database if existing database file is corrupted.
148139 if (!SEGCreateFilePathIfNotExist (dbPath)) {
149- completionHandler (NO ,
150- @{@" ErrorDescription" : @" Could not recreate database file at path" });
140+ completionHandler (
141+ NO ,
142+ @{kSEGErrorDescription : @" Could not recreate database file at path: %@ " , dbpath});
143+ return ;
151144 }
152- if (sqlite3_open_v2 (databasePath, &strongSelf->_database , flags, NULL ) == SQLITE_OK) {
153- if (![strongSelf createTableSchema ]) {
145+ // Try to open the database with the new file.
146+ if (sqlite3_open_v2 (databasePath, &self->_database , flags, NULL ) == SQLITE_OK) {
147+ if (![self createTableSchema ]) {
154148 // Remove database before fail.
155- [strongSelf removeDatabase: dbPath];
149+ [self removeDatabase: dbPath];
156150 // If it failed again, there's nothing we can do here.
157- FIRLogError (kFIRLoggerSegmentation , @" I-SEG000010" , @" Failed to create table." );
151+ FIRLogError (kFIRLoggerSegmentation , @" I-SEG00007" , @" Failed to create table." );
152+ completionHandler (NO , @{kSEGErrorDescription : @" Failed to re-open new database file" });
158153 } else {
159154 // Exclude the app data used from iCloud backup.
160155 SEGAddSkipBackupAttributeToItemAtPath (dbPath);
156+ // Skip reading the db into memory, since it's empty.
157+ completionHandler (YES , @{});
161158 }
162159 } else {
163- [strongSelf logDatabaseError ];
164- completionHandler (NO , @{@" ErrorDescription " : @" Could not create database." });
160+ [self logDatabaseError ];
161+ completionHandler (NO , @{kSEGErrorDescription : @" Could not create database." });
165162 }
166163 }
167164 } else {
168- [strongSelf logDatabaseError ];
169- completionHandler (NO , @{@" ErrorDescription " : @" Error creating database." });
165+ [self logDatabaseError ];
166+ completionHandler (NO , @{kSEGErrorDescription : @" Error creating database." });
170167 }
171168 });
172169}
173170
174171- (void )removeDatabase : (NSString *)path completion : (SEGRequestCompletion)completionHandler {
175172 dispatch_async (_databaseOperationQueue, ^{
176- SEGDatabaseManager *strongSelf = self;
177- if (!strongSelf) {
178- return ;
179- }
180- [strongSelf removeDatabase: path];
173+ [self removeDatabase: path];
181174 completionHandler (YES , nil );
182175 });
183176}
@@ -193,6 +186,8 @@ - (NSDictionary *)loadMainTable {
193186
194187 sqlite3_stmt *statement = [self prepareSQL: [SQLQuery cStringUsingEncoding: NSUTF8StringEncoding]];
195188 if (!statement) {
189+ FIRLogError (kFIRLoggerSegmentation , @" I-SEG00008" ,
190+ @" Failed to create sqlite statement with query: %@ ." , SQLQuery);
196191 return nil ;
197192 }
198193
@@ -279,12 +274,11 @@ - (void)insertMainTableApplicationNamed:(NSString *)firebaseApplication
279274 associationStatus : (NSString *)associationStatus
280275 completionHandler : (SEGRequestCompletion)handler {
281276 // TODO: delete the row first.
282- __weak SEGDatabaseManager *weakSelf = self;
283277 dispatch_async (_databaseOperationQueue, ^{
284- NSArray <NSString *> *values =
285- [[ NSArray alloc ] initWithObjects: firebaseApplication, customInstanceIdentifier,
286- firebaseInstanceIdentifier, associationStatus, nil ];
287- BOOL success = [weakSelf insertMainTableWithValues: values];
278+ NSArray <NSString *> *values = @[
279+ firebaseApplication, customInstanceIdentifier, firebaseInstanceIdentifier, associationStatus
280+ ];
281+ BOOL success = [self insertMainTableWithValues: values];
288282 if (handler) {
289283 dispatch_async (dispatch_get_main_queue (), ^{
290284 handler (success, nil );
@@ -367,7 +361,7 @@ - (BOOL)bindStringsToStatement:(sqlite3_stmt *)statement stringArray:(NSArray *)
367361 int index = 1 ;
368362 for (NSString *param in array) {
369363 if (![self bindStringToStatement: statement index: index string: param]) {
370- return [self logErrorWithSQL: nil finalizeStatement: statement returnValue: NO ];
364+ return [self logErrorWithSQL: sql finalizeStatement: statement returnValue: NO ];
371365 }
372366 index++;
373367 }
@@ -408,6 +402,15 @@ - (BOOL)logErrorWithSQL:(const char *)SQL
408402 returnValue : (BOOL )returnValue {
409403 if (SQL) {
410404 FIRLogError (kFIRLoggerSegmentation , @" I-SEG000016" , @" Failed with SQL: %s ." , SQL);
405+ } else {
406+ const char *sqlString = sqlite3_sql (statement);
407+ NSString *sql;
408+ if (sqlString != NULL ) {
409+ sql = [NSString stringWithCString: sqlString encoding: NSUTF8StringEncoding];
410+ }
411+ if (sql) {
412+ FIRLogError (kFIRLoggerSegmentation , @" I-SEG000016" , @" Failed with SQL: %s ." , SQL);
413+ }
411414 }
412415 [self logDatabaseError ];
413416
0 commit comments