31
31
#define RCNTableNameInternalMetadata " internal_metadata"
32
32
#define RCNTableNameExperiment " experiment"
33
33
#define RCNTableNamePersonalization " personalization"
34
+ #define RCNTableNameRollout " rollout"
34
35
35
36
static BOOL gIsNewDatabase ;
36
37
// / SQLite file name in versions 0, 1 and 2.
@@ -284,11 +285,14 @@ - (BOOL)createTableSchema {
284
285
" create TABLE IF NOT EXISTS " RCNTableNamePersonalization
285
286
" (_id INTEGER PRIMARY KEY, key INTEGER, value BLOB)" ;
286
287
288
+ static const char *createTableRollout = " create TABLE IF NOT EXISTS " RCNTableNameRollout
289
+ " (_id INTEGER PRIMARY KEY, key TEXT, value BLOB)" ;
290
+
287
291
return [self executeQuery: createTableMain] && [self executeQuery: createTableMainActive] &&
288
292
[self executeQuery: createTableMainDefault] && [self executeQuery: createTableMetadata] &&
289
293
[self executeQuery: createTableInternalMetadata] &&
290
294
[self executeQuery: createTableExperiment] &&
291
- [self executeQuery: createTablePersonalization];
295
+ [self executeQuery: createTablePersonalization] && [ self executeQuery: createTableRollout] ;
292
296
}
293
297
294
298
- (void )removeDatabaseOnDatabaseQueueAtPath : (NSString *)path {
@@ -618,6 +622,52 @@ - (BOOL)insertOrUpdatePersonalizationConfig:(NSDictionary *)dataValue
618
622
return YES ;
619
623
}
620
624
625
+ - (void )insertOrUpdateRolloutTableWithKey : (NSString *)key
626
+ value : (NSArray <NSDictionary *> *)value
627
+ completionHandler : (RCNDBCompletion)handler {
628
+ dispatch_async (_databaseOperationQueue, ^{
629
+ BOOL success = [self insertOrUpdateRolloutTableWithKey: key value: value];
630
+ if (handler) {
631
+ dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
632
+ handler (success, nil );
633
+ });
634
+ }
635
+ });
636
+ }
637
+
638
+ - (BOOL )insertOrUpdateRolloutTableWithKey : (NSString *)key
639
+ value : (NSArray <NSDictionary *> *)arrayValue {
640
+ RCN_MUST_NOT_BE_MAIN_THREAD ();
641
+ NSError *error;
642
+ NSData *dataValue = [NSJSONSerialization dataWithJSONObject: arrayValue
643
+ options: NSJSONWritingPrettyPrinted
644
+ error: &error];
645
+ const char *SQL =
646
+ " INSERT OR REPLACE INTO " RCNTableNameRollout
647
+ " (_id, key, value) values ((SELECT _id from " RCNTableNameRollout " WHERE key = ?), ?, ?)" ;
648
+ sqlite3_stmt *statement = [self prepareSQL: SQL];
649
+ if (!statement) {
650
+ return NO ;
651
+ }
652
+ if (![self bindStringToStatement: statement index: 1 string: key]) {
653
+ return [self logErrorWithSQL: SQL finalizeStatement: statement returnValue: NO ];
654
+ }
655
+
656
+ if (![self bindStringToStatement: statement index: 2 string: key]) {
657
+ return [self logErrorWithSQL: SQL finalizeStatement: statement returnValue: NO ];
658
+ }
659
+
660
+ if (sqlite3_bind_blob (statement, 3 , dataValue.bytes , (int )dataValue.length , NULL ) != SQLITE_OK) {
661
+ return [self logErrorWithSQL: SQL finalizeStatement: statement returnValue: NO ];
662
+ }
663
+
664
+ if (sqlite3_step (statement) != SQLITE_DONE) {
665
+ return [self logErrorWithSQL: SQL finalizeStatement: statement returnValue: NO ];
666
+ }
667
+ sqlite3_finalize (statement);
668
+ return YES ;
669
+ }
670
+
621
671
#pragma mark - update
622
672
623
673
- (void )updateMetadataWithOption : (RCNUpdateOption)option
@@ -852,7 +902,6 @@ - (void)loadExperimentWithCompletionHandler:(RCNDBCompletion)handler {
852
902
- (NSMutableArray <NSData *> *)loadExperimentTableFromKey : (NSString *)key {
853
903
RCN_MUST_NOT_BE_MAIN_THREAD ();
854
904
855
- NSMutableArray *results = [[NSMutableArray alloc ] init ];
856
905
const char *SQL = " SELECT value FROM " RCNTableNameExperiment " WHERE key = ?" ;
857
906
sqlite3_stmt *statement = [self prepareSQL: SQL];
858
907
if (!statement) {
@@ -861,12 +910,49 @@ - (void)loadExperimentWithCompletionHandler:(RCNDBCompletion)handler {
861
910
862
911
NSArray *params = @[ key ];
863
912
[self bindStringsToStatement: statement stringArray: params];
864
- NSData *experimentData;
913
+ NSMutableArray *results = [self loadValuesFromStatement: statement];
914
+ return results;
915
+ }
916
+
917
+ - (NSArray <NSDictionary *> *)loadRolloutTableFromKey : (NSString *)key {
918
+ RCN_MUST_NOT_BE_MAIN_THREAD ();
919
+ const char *SQL = " SELECT value FROM " RCNTableNameRollout " WHERE key = ?" ;
920
+ sqlite3_stmt *statement = [self prepareSQL: SQL];
921
+ if (!statement) {
922
+ return nil ;
923
+ }
924
+ NSArray *params = @[ key ];
925
+ [self bindStringsToStatement: statement stringArray: params];
926
+ NSMutableArray *results = [self loadValuesFromStatement: statement];
927
+ // There should be only one entry in this table.
928
+ if (results.count != 1 ) {
929
+ return nil ;
930
+ }
931
+ NSArray *rollout;
932
+ // Convert from NSData to NSArray
933
+ if (results[0 ]) {
934
+ NSError *error;
935
+ rollout = [NSJSONSerialization JSONObjectWithData: results[0 ] options: 0 error: &error];
936
+ if (!rollout) {
937
+ FIRLogError (kFIRLoggerRemoteConfig , @" I-RCN000011" ,
938
+ @" Failed to convert NSData to NSAarry for Rollout Metadata with error %@ ." ,
939
+ error);
940
+ }
941
+ }
942
+ if (!rollout) {
943
+ rollout = [[NSArray alloc ] init ];
944
+ }
945
+ return rollout;
946
+ }
947
+
948
+ - (NSMutableArray *)loadValuesFromStatement : (sqlite3_stmt *)statement {
949
+ NSMutableArray *results = [[NSMutableArray alloc ] init ];
950
+ NSData *value;
865
951
while (sqlite3_step (statement) == SQLITE_ROW) {
866
- experimentData = [NSData dataWithBytes: (char *)sqlite3_column_blob (statement, 0 )
867
- length: sqlite3_column_bytes (statement, 0 )];
868
- if (experimentData ) {
869
- [results addObject: experimentData ];
952
+ value = [NSData dataWithBytes: (char *)sqlite3_column_blob (statement, 0 )
953
+ length: sqlite3_column_bytes (statement, 0 )];
954
+ if (value ) {
955
+ [results addObject: value ];
870
956
}
871
957
}
872
958
@@ -880,7 +966,7 @@ - (void)loadPersonalizationWithCompletionHandler:(RCNDBLoadCompletion)handler {
880
966
RCNConfigDBManager *strongSelf = weakSelf;
881
967
if (!strongSelf) {
882
968
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
883
- handler (NO , [NSMutableDictionary new ], [NSMutableDictionary new ], nil );
969
+ handler (NO , [NSMutableDictionary new ], [NSMutableDictionary new ], nil , nil );
884
970
});
885
971
return ;
886
972
}
@@ -913,7 +999,7 @@ - (void)loadPersonalizationWithCompletionHandler:(RCNDBLoadCompletion)handler {
913
999
914
1000
if (handler) {
915
1001
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
916
- handler (YES , fetchedPersonalization, activePersonalization, nil );
1002
+ handler (YES , fetchedPersonalization, activePersonalization, nil , nil );
917
1003
});
918
1004
}
919
1005
});
@@ -987,7 +1073,7 @@ - (void)loadMainWithBundleIdentifier:(NSString *)bundleIdentifier
987
1073
RCNConfigDBManager *strongSelf = weakSelf;
988
1074
if (!strongSelf) {
989
1075
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
990
- handler (NO , [NSDictionary new ], [NSDictionary new ], [NSDictionary new ]);
1076
+ handler (NO , [NSDictionary new ], [NSDictionary new ], [NSDictionary new ], [ NSDictionary new ] );
991
1077
});
992
1078
return ;
993
1079
}
@@ -1000,12 +1086,26 @@ - (void)loadMainWithBundleIdentifier:(NSString *)bundleIdentifier
1000
1086
__block NSDictionary *defaultConfig =
1001
1087
[strongSelf loadMainTableWithBundleIdentifier: bundleIdentifier
1002
1088
fromSource: RCNDBSourceDefault];
1089
+
1090
+ __block NSArray <NSDictionary *> *fetchedRolloutMetadata =
1091
+ [strongSelf loadRolloutTableFromKey: @RCNRolloutTableKeyFetchedMetadata];
1092
+ __block NSArray <NSDictionary *> *activeRolloutMetadata =
1093
+ [strongSelf loadRolloutTableFromKey: @RCNRolloutTableKeyActiveMetadata];
1094
+
1003
1095
if (handler) {
1004
1096
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
1005
1097
fetchedConfig = fetchedConfig ? fetchedConfig : [[NSDictionary alloc ] init ];
1006
1098
activeConfig = activeConfig ? activeConfig : [[NSDictionary alloc ] init ];
1007
1099
defaultConfig = defaultConfig ? defaultConfig : [[NSDictionary alloc ] init ];
1008
- handler (YES , fetchedConfig, activeConfig, defaultConfig);
1100
+ fetchedRolloutMetadata =
1101
+ fetchedRolloutMetadata ? fetchedRolloutMetadata : [[NSArray alloc ] init ];
1102
+ activeRolloutMetadata =
1103
+ activeRolloutMetadata ? activeRolloutMetadata : [[NSArray alloc ] init ];
1104
+ NSDictionary *rolloutMetadata = @{
1105
+ @RCNRolloutTableKeyActiveMetadata : [activeRolloutMetadata copy ],
1106
+ @RCNRolloutTableKeyFetchedMetadata : [fetchedRolloutMetadata copy ]
1107
+ };
1108
+ handler (YES , fetchedConfig, activeConfig, defaultConfig, rolloutMetadata);
1009
1109
});
1010
1110
}
1011
1111
});
0 commit comments