From 5f0f571b419c7521d379232ae098c18c2dc86ef0 Mon Sep 17 00:00:00 2001 From: Pallab Maiti Date: Thu, 28 Sep 2023 15:06:57 +0530 Subject: [PATCH] fix: workaround for RETURNING clause --- Podfile.lock | 2 +- Sources/Classes/Headers/Public/RSDatabase.h | 1 + Sources/Classes/RSDBPersistentManager.m | 34 ++++++++++++++++----- Sources/Classes/RSDefaultDatabase.m | 5 +++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 0eb8ecb4..a6be8e94 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -39,4 +39,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: b6937cee06e0633464427ff0d975d40e17419e9f -COCOAPODS: 1.12.0 +COCOAPODS: 1.13.0 diff --git a/Sources/Classes/Headers/Public/RSDatabase.h b/Sources/Classes/Headers/Public/RSDatabase.h index 74ac47aa..9dccc6d6 100644 --- a/Sources/Classes/Headers/Public/RSDatabase.h +++ b/Sources/Classes/Headers/Public/RSDatabase.h @@ -25,6 +25,7 @@ typedef int (*callback)(void * _Nullable, int, char * _Nullable * _Nullable, cha - (const unsigned char *)column_text:(void * _Nullable)pStmt i:(int)i; - (int)key:(const void * _Nullable)pKey nKey:(int)nKey; +- (int)last_insert_rowid; @end diff --git a/Sources/Classes/RSDBPersistentManager.m b/Sources/Classes/RSDBPersistentManager.m index e9b281f4..7265f565 100644 --- a/Sources/Classes/RSDBPersistentManager.m +++ b/Sources/Classes/RSDBPersistentManager.m @@ -28,6 +28,7 @@ @implementation RSDBPersistentManager { NSLock* lock; id database; + BOOL isReturnClauseSupported; } - (instancetype)initWithDBEncryption:(RSDBEncryption * __nullable)dbEncryption { @@ -36,6 +37,12 @@ - (instancetype)initWithDBEncryption:(RSDBEncryption * __nullable)dbEncryption { self->lock = [[NSLock alloc] init]; self->database = [[self getDatabaseProvider:dbEncryption] getDatabase]; [self createDB:dbEncryption]; + isReturnClauseSupported = [self doesReturnClauseExists]; + if(isReturnClauseSupported) { + [RSLogger logVerbose:@"RSDBPersistentManager: init: SQLiteVersion is >=3.35.0, hence return clause can be used"]; + } else { + [RSLogger logVerbose:@"RSDBPersistentManager: init: SQLiteVersion is <3.35.0, hence return clause cannot be used"]; + } } return self; } @@ -313,8 +320,12 @@ -(void) createEventsTableWithVersion:(int) version { } - (NSNumber*)saveEvent:(NSString *)message { - NSString *insertSQLString = [[NSString alloc] initWithFormat:@"INSERT INTO %@ (%@, %@) VALUES ('%@', %ld) RETURNING %@;", TABLE_EVENTS, COL_MESSAGE, COL_UPDATED, [message stringByReplacingOccurrencesOfString:@"'" withString:@"''"], [RSUtils getTimeStampLong], COL_ID]; - + NSString *insertSQLString; + if(isReturnClauseSupported) { + insertSQLString = [[NSString alloc] initWithFormat:@"INSERT INTO %@ (%@, %@) VALUES ('%@', %ld) RETURNING %@;", TABLE_EVENTS, COL_MESSAGE, COL_UPDATED, [message stringByReplacingOccurrencesOfString:@"'" withString:@"''"], [RSUtils getTimeStampLong], COL_ID]; + } else { + insertSQLString = [[NSString alloc] initWithFormat:@"INSERT INTO %@ (%@, %@) VALUES ('%@', %ld);", TABLE_EVENTS, COL_MESSAGE, COL_UPDATED, [message stringByReplacingOccurrencesOfString:@"'" withString:@"''"], [RSUtils getTimeStampLong]]; + } [RSLogger logDebug:[[NSString alloc] initWithFormat:@"RSDBPersistentManager: saveEventSQL: %@", insertSQLString]]; const char* insertSQL = [insertSQLString UTF8String]; @@ -322,14 +333,21 @@ - (NSNumber*)saveEvent:(NSString *)message { void *insertStmt = nil; [self->lock lock]; if ([database prepare_v2:insertSQL nBytes:-1 ppStmt:&insertStmt pzTail:NULL] == SQLITE_OK) { - if ([database step:insertStmt] == SQLITE_ROW) { - // table created - [RSLogger logDebug:@"RSDBPersistentManager: saveEvent: Successfully inserted event to table"]; - rowId = [database column_int:insertStmt i:0]; + if(isReturnClauseSupported) { + if ([database step:insertStmt] == SQLITE_ROW) { + // table created + [RSLogger logDebug:@"RSDBPersistentManager: saveEvent: Successfully inserted event to table"]; + rowId = sqlite3_column_int(insertStmt, 0); + } else { + [RSLogger logError:@"RSDBPersistentManager: saveEvent: Failed to insert the event"]; + } + [database finalize:insertStmt]; } else { - [RSLogger logError:@"RSDBPersistentManager: saveEvent: Failed to insert the event"]; + if([database step:insertStmt] == SQLITE_DONE) { + [database finalize:insertStmt]; + rowId = [database last_insert_rowid]; + } } - [database finalize:insertStmt]; } else { [RSLogger logError:@"RSDBPersistentManager: saveEvent: SQLite Command Preparation Failed"]; } diff --git a/Sources/Classes/RSDefaultDatabase.m b/Sources/Classes/RSDefaultDatabase.m index 99a1d5fe..5933a60e 100644 --- a/Sources/Classes/RSDefaultDatabase.m +++ b/Sources/Classes/RSDefaultDatabase.m @@ -48,4 +48,9 @@ - (int)key:(const void *)pKey nKey:(int)nKey { return -1; } +- (int)last_insert_rowid { + int64_t lastRowId = sqlite3_last_insert_rowid(db); + return (int)lastRowId; +} + @end