@@ -38,16 +38,16 @@ static BOOL SEGAddSkipBackupAttributeToItemAtPath(NSString *filePathString) {
38
38
NSError *error = nil ;
39
39
BOOL success = [URL setResourceValue: @YES forKey: NSURLIsExcludedFromBackupKey error: &error];
40
40
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);
43
43
}
44
44
return success;
45
45
}
46
46
47
47
static 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." );
51
51
return NO ;
52
52
}
53
53
NSFileManager *fileManager = [NSFileManager defaultManager ];
@@ -58,23 +58,20 @@ static BOOL SEGCreateFilePathIfNotExist(NSString *filePath) {
58
58
attributes: nil
59
59
error: &error];
60
60
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);
63
63
return NO ;
64
64
}
65
65
}
66
66
return YES ;
67
67
}
68
68
69
- @interface SEGDatabaseManager () {
69
+ @implementation SEGDatabaseManager {
70
70
// / Database storing all the config information.
71
71
sqlite3 *_database;
72
72
// / Serial queue for database read/write operations.
73
73
dispatch_queue_t _databaseOperationQueue;
74
74
}
75
- @end
76
-
77
- @implementation SEGDatabaseManager
78
75
79
76
+ (instancetype )sharedInstance {
80
77
static dispatch_once_t onceToken;
@@ -97,41 +94,35 @@ - (instancetype)init {
97
94
#pragma mark - Public Methods
98
95
99
96
- (void )loadMainTableWithCompletion : (SEGRequestCompletion)completionHandler {
100
- __weak SEGDatabaseManager *weakSelf = self;
101
97
dispatch_async (_databaseOperationQueue, ^{
102
- SEGDatabaseManager *strongSelf = weakSelf;
103
- if (!strongSelf) {
104
- completionHandler (NO , @{@" Database Error" : @" Internal database error" });
105
- }
106
-
107
98
// Read the database into memory.
108
99
NSDictionary <NSString *, NSDictionary <NSString *, NSString *> *> *associations =
109
100
[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
+ }
111
107
});
112
108
return ;
113
109
}
114
110
115
111
- (void )createOrOpenDatabaseWithCompletion : (SEGRequestCompletion)completionHandler {
116
- __weak SEGDatabaseManager *weakSelf = self;
117
112
dispatch_async (_databaseOperationQueue, ^{
118
- SEGDatabaseManager *strongSelf = weakSelf;
119
- if (!strongSelf) {
120
- completionHandler (NO , @{@" ErrorDescription" : @" Internal database error" });
121
- }
122
113
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);
125
116
const char *databasePath = dbPath.UTF8String ;
126
117
// Create or open database path.
127
118
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" });
129
120
}
130
121
int flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FILEPROTECTION_COMPLETE |
131
122
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) {
133
124
// Create table if does not exist already.
134
- if ([strongSelf createTableSchema ]) {
125
+ if ([self createTableSchema ]) {
135
126
// DB file created or already exists.
136
127
// Exclude the app data used from iCloud backup.
137
128
SEGAddSkipBackupAttributeToItemAtPath (dbPath);
@@ -142,42 +133,44 @@ - (void)createOrOpenDatabaseWithCompletion:(SEGRequestCompletion)completionHandl
142
133
143
134
} else {
144
135
// 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." );
147
138
// Create a new database if existing database file is corrupted.
148
139
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 ;
151
144
}
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 ]) {
154
148
// Remove database before fail.
155
- [strongSelf removeDatabase: dbPath];
149
+ [self removeDatabase: dbPath];
156
150
// 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" });
158
153
} else {
159
154
// Exclude the app data used from iCloud backup.
160
155
SEGAddSkipBackupAttributeToItemAtPath (dbPath);
156
+ // Skip reading the db into memory, since it's empty.
157
+ completionHandler (YES , @{});
161
158
}
162
159
} else {
163
- [strongSelf logDatabaseError ];
164
- completionHandler (NO , @{@" ErrorDescription " : @" Could not create database." });
160
+ [self logDatabaseError ];
161
+ completionHandler (NO , @{kSEGErrorDescription : @" Could not create database." });
165
162
}
166
163
}
167
164
} else {
168
- [strongSelf logDatabaseError ];
169
- completionHandler (NO , @{@" ErrorDescription " : @" Error creating database." });
165
+ [self logDatabaseError ];
166
+ completionHandler (NO , @{kSEGErrorDescription : @" Error creating database." });
170
167
}
171
168
});
172
169
}
173
170
174
171
- (void )removeDatabase : (NSString *)path completion : (SEGRequestCompletion)completionHandler {
175
172
dispatch_async (_databaseOperationQueue, ^{
176
- SEGDatabaseManager *strongSelf = self;
177
- if (!strongSelf) {
178
- return ;
179
- }
180
- [strongSelf removeDatabase: path];
173
+ [self removeDatabase: path];
181
174
completionHandler (YES , nil );
182
175
});
183
176
}
@@ -193,6 +186,8 @@ - (NSDictionary *)loadMainTable {
193
186
194
187
sqlite3_stmt *statement = [self prepareSQL: [SQLQuery cStringUsingEncoding: NSUTF8StringEncoding]];
195
188
if (!statement) {
189
+ FIRLogError (kFIRLoggerSegmentation , @" I-SEG00008" ,
190
+ @" Failed to create sqlite statement with query: %@ ." , SQLQuery);
196
191
return nil ;
197
192
}
198
193
@@ -279,12 +274,11 @@ - (void)insertMainTableApplicationNamed:(NSString *)firebaseApplication
279
274
associationStatus : (NSString *)associationStatus
280
275
completionHandler : (SEGRequestCompletion)handler {
281
276
// TODO: delete the row first.
282
- __weak SEGDatabaseManager *weakSelf = self;
283
277
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];
288
282
if (handler) {
289
283
dispatch_async (dispatch_get_main_queue (), ^{
290
284
handler (success, nil );
@@ -367,7 +361,7 @@ - (BOOL)bindStringsToStatement:(sqlite3_stmt *)statement stringArray:(NSArray *)
367
361
int index = 1 ;
368
362
for (NSString *param in array) {
369
363
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 ];
371
365
}
372
366
index++;
373
367
}
@@ -408,6 +402,15 @@ - (BOOL)logErrorWithSQL:(const char *)SQL
408
402
returnValue : (BOOL )returnValue {
409
403
if (SQL) {
410
404
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
+ }
411
414
}
412
415
[self logDatabaseError ];
413
416
0 commit comments