Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: replay message queue dumping logic #348

Merged
merged 3 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ PODS:
- Rudder-Braze (1.2.0):
- Appboy-iOS-SDK (~> 4.5.4)
- Rudder (~> 1.12)
- SDWebImage (5.16.0):
- SDWebImage/Core (= 5.16.0)
- SDWebImage/Core (5.16.0)
- SDWebImage (5.17.0):
- SDWebImage/Core (= 5.17.0)
- SDWebImage/Core (5.17.0)

DEPENDENCIES:
- Amplitude (~> 7.2.0)
Expand Down Expand Up @@ -124,7 +124,7 @@ SPEC CHECKSUMS:
Rudder: 718bc5bf0de0e4d83850dedd792f08e5e2065a0a
Rudder-Amplitude: f845cc125a1a58d4de6155391a2b0392815ae898
Rudder-Braze: e42eb914a03cb418ed8b7a3cd90b724a91476631
SDWebImage: 2aea163b50bfcb569a2726b6a754c54a4506fcf6
SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9

PODFILE CHECKSUM: 42bfa6ba9271b8d9518a669daca1fd9a7bbf9f6e

Expand Down
1 change: 1 addition & 0 deletions Sources/Classes/Headers/Public/RSDBMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) NSMutableArray<NSString *>* messages;
@property (nonatomic) NSMutableArray<NSString *>* messageIds;
@property (nonatomic) NSMutableArray<NSNumber *>* statusList;
@property (nonatomic) NSMutableArray<NSNumber *>* dmProcessed;
@end

NS_ASSUME_NONNULL_END
10 changes: 6 additions & 4 deletions Sources/Classes/Headers/Public/RSDBPersistentManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ NS_ASSUME_NONNULL_BEGIN
-(void) createTables;
-(void) createEventsTableWithVersion:(int) version;
-(void) checkForMigrations;
-(BOOL) checkIfStatusColumnExists;
-(void) performMigration;
-(BOOL) checkIfColumnExists:(NSString *) newColumn;
-(void) performMigration:(NSString *) columnName;
-(NSNumber*) saveEvent: (NSString*) message;
- (void) clearOldEventsWithThreshold:(int)threshold;
-(void) clearEventsFromDB: (NSMutableArray*) messageIds;
Expand All @@ -36,8 +36,10 @@ NS_ASSUME_NONNULL_BEGIN
-(void) clearProcessedEventsFromDB;
- (int) getDBRecordCountForMode:(MODES) mode;
-(void) flushEventsFromDB;
-(void) updateDeviceModeEventsStatus;

-(RSDBMessage*)fetchDeviceModeWithProcessedPendingEventsFromDb:(int) limit;
-(int) getDeviceModeWithProcessedPendingEventsRecordCount;
-(void) markDeviceModeTransformationAndProcessedDone:(NSNumber *) messageId;
-(void) markDeviceModeProcessedDone:(NSNumber *) messageId;
@end

NS_ASSUME_NONNULL_END
5 changes: 5 additions & 0 deletions Sources/Classes/Headers/Public/RSEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ typedef enum {
ALL = 3
} MODES;

typedef enum {
DM_PROCESSED_PENDING =0,
DM_PROCESSED_DONE =1,
} DM_PROCESSED;

typedef enum {
ENABLED = YES,
DISABLED = NO
Expand Down
3 changes: 0 additions & 3 deletions Sources/Classes/Headers/Public/RSPreferenceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ extern NSString *const RSSessionAutoTrackStatus;
- (void) saveAutoTrackingStatus: (BOOL) autoTrackingStatus;
- (BOOL) getAutoTrackingStatus;

- (void) saveEventDeletionStatus;
- (BOOL) getEventDeletionStatus;

@end

NS_ASSUME_NONNULL_END
124 changes: 88 additions & 36 deletions Sources/Classes/RSDBPersistentManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
#import "RSDBPersistentManager.h"
#import "RSLogger.h"

int const RS_DB_Version = 2;
int const RS_DB_Version = 3;
int const DEFAULT_STATUS_VALUE = 0;
bool isReturnClauseSupported = NO;
NSString* _Nonnull const TABLE_EVENTS = @"events";
NSString* _Nonnull const COL_ID = @"id";
NSString* _Nonnull const COL_MESSAGE = @"message";
NSString* _Nonnull const COL_UPDATED = @"updated";
NSString* _Nonnull const COL_STATUS = @"status";
NSString* _Nonnull const COL_DM_PROCESSED = @"dm_processed";


@implementation RSDBPersistentManager
Expand Down Expand Up @@ -47,44 +48,62 @@ - (void)createDB {
// Migration is needed when an application is updated to the latest version of SDK from a version which doesn't has the status column in its events table
- (void)checkForMigrations {
[RSLogger logDebug:@"RSDBPersistentManager: checkForMigrations: checking if the event table has status column"];
if(![self checkIfStatusColumnExists]) {
bool isNewColumnAdded = NO;
if(![self checkIfColumnExists:COL_STATUS]) {
[RSLogger logDebug:@"RSDBPersistentManager: checkForMigrations: events table doesn't has the status column performing migration"];
[self performMigration];
return;
[self performMigration:COL_STATUS];
isNewColumnAdded = YES;
}
if(![self checkIfColumnExists:COL_DM_PROCESSED]) {
[RSLogger logDebug:@"RSDBPersistentManager: checkForMigrations: events table doesn't has the dm_processed column performing migration"];
[self performMigration:COL_DM_PROCESSED];
isNewColumnAdded = YES;
}
if (!isNewColumnAdded) {
[RSLogger logDebug:@"RSDBPersistentManager: checkForMigrations: event table has status and dm_processed columns, no migration required"];
}
[RSLogger logDebug:@"RSDBPersistentManager: checkForMigrations: event table has status column, no migration required"];
}

- (BOOL) checkIfStatusColumnExists {
NSString* checkIfStatusExistsSQLString = [[NSString alloc] initWithFormat:@"SELECT COUNT(*) from pragma_table_info(\"%@\") where name=\"%@\";", TABLE_EVENTS, COL_STATUS];
const char* statusCheckSQL = [checkIfStatusExistsSQLString UTF8String];
sqlite3_stmt *statusCheckStmt = nil;
BOOL statusColumnExists = NO;
if (sqlite3_prepare_v2(self->_database, statusCheckSQL, -1, &statusCheckStmt, nil) == SQLITE_OK) {
if(sqlite3_step(statusCheckStmt) == SQLITE_ROW) {
int count = sqlite3_column_int(statusCheckStmt, 0);
- (BOOL) checkIfColumnExists:(NSString *) newColumn {
NSString* checkIfNewColumnExistsSQLString = [[NSString alloc] initWithFormat:@"SELECT COUNT(*) from pragma_table_info(\"%@\") where name=\"%@\";", TABLE_EVENTS, newColumn];
const char* newColumnCheckSQL = [checkIfNewColumnExistsSQLString UTF8String];
sqlite3_stmt *newColumnCheckStmt = nil;
BOOL newColumnExists = NO;
if (sqlite3_prepare_v2(self->_database, newColumnCheckSQL, -1, &newColumnCheckStmt, nil) == SQLITE_OK) {
if(sqlite3_step(newColumnCheckStmt) == SQLITE_ROW) {
int count = sqlite3_column_int(newColumnCheckStmt, 0);
if(count > 0) {
statusColumnExists = YES;
newColumnExists = YES;
}
}
else {
[RSLogger logWarn:[[NSString alloc] initWithFormat: @"RSDBPersistentManager: checkIfStatusColumnExists: SQLite Command Execution Failed: %@", checkIfStatusExistsSQLString]];
[RSLogger logWarn:[[NSString alloc] initWithFormat: @"RSDBPersistentManager: checkIfStatusColumnExists: SQLite Command Execution Failed: %@", checkIfNewColumnExistsSQLString]];
}
}
else {
[RSLogger logError:[[NSString alloc] initWithFormat: @"RSDBPersistentManager: checkIfStatusColumnExists: SQLite Command Preparation Failed: %@", checkIfStatusExistsSQLString]];
[RSLogger logError:[[NSString alloc] initWithFormat: @"RSDBPersistentManager: checkIfStatusColumnExists: SQLite Command Preparation Failed: %@", checkIfNewColumnExistsSQLString]];
}
sqlite3_finalize(statusCheckStmt);
return statusColumnExists;
sqlite3_finalize(newColumnCheckStmt);
return newColumnExists;
}

- (void) performMigration {
NSString* alterTableSQLString = [[NSString alloc] initWithFormat:@"ALTER TABLE %@ ADD COLUMN %@ INTEGER DEFAULT %d;", TABLE_EVENTS, COL_STATUS, DEFAULT_STATUS_VALUE];
NSString* updateTableSQLString = [[NSString alloc] initWithFormat:@"UPDATE %@ SET %@ = %d;", TABLE_EVENTS, COL_STATUS, DEVICE_MODE_PROCESSING_DONE];

if([self execSQL:alterTableSQLString] && [self execSQL:updateTableSQLString]) {
[RSLogger logDebug:@"RSDBPersistentManager: performMigration: events table migrated to add status column"];
return;
- (void) performMigration:(NSString *) columnName {
if ([columnName isEqualToString:COL_STATUS]) {
NSString* alterTableSQLString = [[NSString alloc] initWithFormat:@"ALTER TABLE %@ ADD COLUMN %@ INTEGER DEFAULT %d;", TABLE_EVENTS, COL_STATUS, DEFAULT_STATUS_VALUE];
NSString* updateTableSQLString = [[NSString alloc] initWithFormat:@"UPDATE %@ SET %@ = %d;", TABLE_EVENTS, COL_STATUS, DEVICE_MODE_PROCESSING_DONE];

if([self execSQL:alterTableSQLString] && [self execSQL:updateTableSQLString]) {
[RSLogger logDebug:@"RSDBPersistentManager: performMigration: events table migrated to add status column"];
return;
}
} else if ([columnName isEqualToString:COL_DM_PROCESSED]) {
NSString* alterTableSQLString = [[NSString alloc] initWithFormat:@"ALTER TABLE %@ ADD COLUMN %@ INTEGER DEFAULT %d;", TABLE_EVENTS, COL_DM_PROCESSED, DM_PROCESSED_PENDING];
NSString* updateTableSQLString = [[NSString alloc] initWithFormat:@"UPDATE %@ SET %@ = (%@ | %d), %@ = %d;", TABLE_EVENTS, COL_STATUS, COL_STATUS, DEVICE_MODE_PROCESSING_DONE, COL_DM_PROCESSED, DM_PROCESSED_DONE];

if([self execSQL:alterTableSQLString] && [self execSQL:updateTableSQLString]) {
[RSLogger logDebug:@"RSDBPersistentManager: performMigration: events table migrated to add dm_processed column"];
return;
}
}
[RSLogger logError:@"RSDBPersistentManager: performMigration: events table migration failed"];
}
Expand All @@ -99,6 +118,9 @@ -(void) createEventsTableWithVersion:(int) version {
case 1:
createTableSQLString = [[NSString alloc] initWithFormat:@"CREATE TABLE IF NOT EXISTS %@( %@ INTEGER PRIMARY KEY AUTOINCREMENT, %@ TEXT NOT NULL, %@ INTEGER NOT NULL);", TABLE_EVENTS, COL_ID, COL_MESSAGE, COL_UPDATED];
break;
case 3:
createTableSQLString = [[NSString alloc] initWithFormat:@"CREATE TABLE IF NOT EXISTS %@( %@ INTEGER PRIMARY KEY AUTOINCREMENT, %@ TEXT NOT NULL, %@ INTEGER NOT NULL, %@ INTEGER DEFAULT %d, %@ INTEGER DEFAULT %d);", TABLE_EVENTS, COL_ID, COL_MESSAGE, COL_UPDATED, COL_STATUS, DEFAULT_STATUS_VALUE, COL_DM_PROCESSED, DM_PROCESSED_PENDING];
break;
default:
createTableSQLString = [[NSString alloc] initWithFormat:@"CREATE TABLE IF NOT EXISTS %@( %@ INTEGER PRIMARY KEY AUTOINCREMENT, %@ TEXT NOT NULL, %@ INTEGER NOT NULL, %@ INTEGER DEFAULT %d);", TABLE_EVENTS, COL_ID, COL_MESSAGE, COL_UPDATED, COL_STATUS, DEFAULT_STATUS_VALUE];
}
Expand Down Expand Up @@ -174,17 +196,6 @@ - (void)clearEventsFromDB:(NSMutableArray<NSString *> *)messageIds {
}
}

-(void) updateDeviceModeEventsStatus {
NSString* updateEventStatusSQL = [[NSString alloc] initWithFormat:@"UPDATE %@ SET %@ = (%@ | %d) WHERE %@ IN (%d, %d);", TABLE_EVENTS, COL_STATUS, COL_STATUS, DEVICE_MODE_PROCESSING_DONE, COL_STATUS, NOT_PROCESSED, CLOUD_MODE_PROCESSING_DONE];
@synchronized (self) {
if([self execSQL:updateEventStatusSQL]) {
[RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: updateDeviceModeEventsStatus: Successfully updated the event status for unprocessed and cloud mode processing done events to device mode processing done."]];
return;
}
[RSLogger logError:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: updateDeviceModeEventsStatuse: Failed to update the status for events."]];
}
}

-(RSDBMessage *)fetchEventsFromDB:(int)count ForMode:(MODES) mode {
NSString* querySQLString = nil;
switch(mode) {
Expand Down Expand Up @@ -221,6 +232,7 @@ - (RSDBMessage *) getEventsFromDB :(NSString*) querySQLString {
NSMutableArray<NSString *> *messageIds = [[NSMutableArray alloc] init];
NSMutableArray<NSString *> *messages = [[NSMutableArray alloc] init];
NSMutableArray<NSNumber *>* statusList = [[NSMutableArray alloc] init];
NSMutableArray<NSNumber *>* dmProcessedList = [[NSMutableArray alloc] init];

@synchronized (self) {
sqlite3_stmt *queryStmt = nil;
Expand All @@ -231,9 +243,11 @@ - (RSDBMessage *) getEventsFromDB :(NSString*) querySQLString {
const unsigned char* queryResultCol1 = sqlite3_column_text(queryStmt, 1);
NSString *message = [[NSString alloc] initWithUTF8String:(char *)queryResultCol1];
int status = sqlite3_column_int(queryStmt,3);
int dmProcessed = sqlite3_column_int(queryStmt, 4);
[messageIds addObject:[[NSString alloc] initWithFormat:@"%d", messageId]];
[messages addObject:message];
[statusList addObject:[NSNumber numberWithInt:status]];
[dmProcessedList addObject:[NSNumber numberWithInt:dmProcessed]];
}
} else {
[RSLogger logError:@"RSDBPersistentManager: getEventsFromDB: Failed to fetch events from DB"];
Expand All @@ -244,6 +258,7 @@ - (RSDBMessage *) getEventsFromDB :(NSString*) querySQLString {
dbMessage.messageIds = messageIds;
dbMessage.messages = messages;
dbMessage.statusList = statusList;
dbMessage.dmProcessed = dmProcessedList;
return dbMessage;
}

Expand All @@ -261,6 +276,10 @@ - (int) getDBRecordCountForMode:(MODES) mode {
countSQLString = [[NSString alloc] initWithFormat:@"SELECT COUNT(*) FROM %@", TABLE_EVENTS];
}
[RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: getDBRecordCount: countSQLString: %@", countSQLString]];
return [self getDBRecordCoun:countSQLString];
}

-(int) getDBRecordCoun:(NSString *) countSQLString {
int count = 0;
const char* countSQL = [countSQLString UTF8String];
@synchronized (self) {
Expand Down Expand Up @@ -368,4 +387,37 @@ - (NSString *) getSQLiteVersion {
}
return sqliteVersion;
}

-(RSDBMessage*)fetchDeviceModeWithProcessedPendingEventsFromDb:(int) limit {
NSString* querySQLString = [[NSString alloc] initWithFormat:@"SELECT * FROM %@ WHERE %@ IN (%d,%d) AND %@ = %d ORDER BY %@ ASC LIMIT %d;", TABLE_EVENTS, COL_STATUS, NOT_PROCESSED, CLOUD_MODE_PROCESSING_DONE, COL_DM_PROCESSED, DM_PROCESSED_PENDING, COL_UPDATED, limit];
return [self getEventsFromDB:querySQLString];
}

-(int) getDeviceModeWithProcessedPendingEventsRecordCount {
NSString *countSQLString = [[NSString alloc] initWithFormat:@"SELECT COUNT(*) FROM %@ where %@ IN (%d,%d) AND %@ = %d", TABLE_EVENTS, COL_STATUS, NOT_PROCESSED, CLOUD_MODE_PROCESSING_DONE, COL_DM_PROCESSED, DM_PROCESSED_PENDING];
[RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: getDeviceModeWithProcessedPendingEventsRecordCount: countSQLString: %@", countSQLString]];
return [self getDBRecordCoun:countSQLString];
}

-(void) markDeviceModeTransformationAndProcessedDone:(NSNumber *) messageId {
NSString* updateEventStatusSQL = [[NSString alloc] initWithFormat:@"UPDATE %@ SET %@ = %@ | %d, %@ = %d WHERE %@ = %@;", TABLE_EVENTS, COL_STATUS, COL_STATUS, DEVICE_MODE_PROCESSING_DONE, COL_DM_PROCESSED, DM_PROCESSED_DONE, COL_ID, messageId];
@synchronized (self) {
if([self execSQL:updateEventStatusSQL]) {
[RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: markDeviceModeTransformationAndProcessedDone: Successfully updated the event status and dm_processed columns for events %@", messageId]];
return;
}
[RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: markDeviceModeTransformationAndProcessedDone: Failed to update the event status and dm_processed columns for events %@", messageId]];
}
}

-(void) markDeviceModeProcessedDone:(NSNumber *) messageId {
NSString* updateEventStatusSQL = [[NSString alloc] initWithFormat:@"UPDATE %@ SET %@ = %d WHERE %@ = %@;", TABLE_EVENTS, COL_DM_PROCESSED, DM_PROCESSED_DONE, COL_ID, messageId];
@synchronized (self) {
if([self execSQL:updateEventStatusSQL]) {
[RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: markDeviceModeProcessedDone: Successfully updated the event dm_processed for events %@", messageId]];
return;
}
[RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: markDeviceModeProcessedDone: Failed to update the dm_processed for events %@", messageId]];
}
}
@end
Loading
Loading