diff --git a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.h b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.h index 9d1e1eb02..d1b80c4e5 100644 --- a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.h +++ b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.h @@ -6,6 +6,7 @@ */ #import +#include @interface DatabaseExecuteSqlResponse : NSObject @@ -15,6 +16,12 @@ @property(nonatomic, strong) NSNumber* insertedId; @property(nonatomic, assign) NSInteger affectedCount; +- (instancetype)initWithType:(NSString*)type + columns:(NSArray*)columns + values:(NSArray*)values + insertedId:(NSNumber*)insertedId + affectedCount:(NSInteger)affectedCount; + @end @interface DatabaseExecuteSqlRequest : NSObject @@ -23,5 +30,7 @@ @property(nonatomic, copy, readonly) NSString* value; - (instancetype)initWithDatabaseId:(NSInteger)databaseId value:(NSString*)value; ++ (DatabaseExecuteSqlRequest*)getExecuteSqlRequestFromDictionary: + (NSDictionary*)dictionary; @end diff --git a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.m b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.m index 96494e8d5..a63981717 100644 --- a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.m +++ b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Commands/DatabaseExecuteSql.m @@ -6,6 +6,7 @@ */ #include "DatabaseExecuteSql.h" +#include @implementation DatabaseExecuteSqlResponse @@ -39,4 +40,15 @@ return self; } ++ (DatabaseExecuteSqlRequest*)getExecuteSqlRequestFromDictionary: + (NSDictionary*)dictionary { + NSInteger databaseId = [dictionary[@"databaseId"] integerValue]; + NSString* value = dictionary[@"value"]; + if (databaseId <= 0 || value.length == 0) { + return nil; + } + return [[DatabaseExecuteSqlRequest alloc] initWithDatabaseId:databaseId + value:value]; +} + @end diff --git a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabaseDriver.h b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabaseDriver.h index 0d227761e..140ba3387 100644 --- a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabaseDriver.h +++ b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabaseDriver.h @@ -11,6 +11,7 @@ @class DatabaseGetTableStructureResponse; @class DatabaseGetTableInfoResponse; @class DatabaseGetTableDataResponse; +@class DatabaseExecuteSqlResponse; @protocol DatabaseDriver - (NSArray>*)getDatabases; @@ -32,4 +33,5 @@ reverse:(BOOL)reverse start:(NSInteger)start count:(NSInteger)count; +- (DatabaseExecuteSqlResponse*)executeSQL:(NSString*)sql; @end diff --git a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabasesManager.m b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabasesManager.m index 0fbc0f4ff..939969251 100644 --- a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabasesManager.m +++ b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/DatabasesManager.m @@ -14,6 +14,7 @@ #import "DatabaseDescriptorHolder.h" #import "DatabaseDriver.h" #import "DatabaseErrorCodes.h" +#import "DatabaseExecuteSql.h" #import "DatabaseGetTableData.h" #import "DatabaseGetTableInfo.h" #import "DatabaseGetTableStructure.h" @@ -213,7 +214,38 @@ [self.connection receive:@"execute" - withBlock:^(NSDictionary* params, id responder){ + withBlock:^(NSDictionary* params, id responder) { + DatabaseExecuteSqlRequest* request = [DatabaseExecuteSqlRequest + getExecuteSqlRequestFromDictionary:params]; + if (!request) { + NSDictionary* errorResponse = [ObjectMapper + errorWithCode:DatabasesErrorCodesInvalidRequest + message:kDatabasesErrorCodesInvalidRequestMessage]; + [responder error:errorResponse]; + return; + } + DatabaseDescriptorHolder* descriptorHolder = + self.databaseDescriptorHolders[@(request.databaseId)]; + if (!descriptorHolder) { + NSDictionary* errorResponse = [ObjectMapper + errorWithCode:DatabasesErrorCodesDatabaseInvalid + message:kDatabasesErrorCodesDatabaseInvalidMessage]; + [responder error:errorResponse]; + return; + } + @try { + DatabaseExecuteSqlResponse* sqlResponse = + [descriptorHolder.databaseDriver executeSQL:request.value]; + NSDictionary* response = + [ObjectMapper databaseExecuteSqlResponseToDictionary:sqlResponse]; + [responder success:response]; + } @catch (NSException* exception) { + NSDictionary* errorResponse = [ObjectMapper + errorWithCode:DatabasesErrorCodesSqlExecutionException + message:[kDatabasesErrorCodesSqlExecutionExceptionMessage + stringByAppendingString:exception.reason]]; + [responder error:errorResponse]; + } }]; } diff --git a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Mock/MockDatabaseDriver.m b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Mock/MockDatabaseDriver.m index 0f7563b8e..8a153059f 100644 --- a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Mock/MockDatabaseDriver.m +++ b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/Mock/MockDatabaseDriver.m @@ -6,6 +6,7 @@ */ #import "MockDatabaseDriver.h" +#import "DatabaseExecuteSql.h" #import "DatabaseGetTableData.h" #import "DatabaseGetTableInfo.h" #import "DatabaseGetTableStructure.h" @@ -80,4 +81,39 @@ total:100]; } +- (DatabaseExecuteSqlResponse*)executeSQL:(NSString*)sql { + // Generate a mock response with a random type + NSString* type; + NSArray* columns = @[ @"id", @"name" ]; + NSMutableArray* values = [NSMutableArray array]; + for (int i = 0; i < 100; i++) { + [values addObject:@[ @(i), [NSString stringWithFormat:@"Name %d", i] ]]; + } + + // Randomly select a type + NSArray* types = @[ @"SELECT", @"INSERT", @"UPDATE", @"DELETE" ]; + int index = arc4random_uniform((u_int32_t)types.count); + type = types[index]; + + // Set affectedCount and insertedId based on type + NSInteger affectedCount = 0; + NSNumber* insertedId = nil; + if ([type isEqualToString:@"INSERT"]) { + affectedCount = 1; + insertedId = @(15); + } else if ( + [type isEqualToString:@"UPDATE"] || [type isEqualToString:@"DELETE"]) { + affectedCount = values.count; + } + + DatabaseExecuteSqlResponse* response = + [[DatabaseExecuteSqlResponse alloc] initWithType:type + columns:columns + values:[values copy] + insertedId:insertedId + affectedCount:affectedCount]; + + return response; +} + @end diff --git a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/ObjectMapper.m b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/ObjectMapper.m index 16e007f4e..5b3f13409 100644 --- a/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/ObjectMapper.m +++ b/iOS/Plugins/FlipperKitDatabasesPlugin/FlipperKitDatabasesPlugin/ObjectMapper.m @@ -83,7 +83,29 @@ static NSString* const UNKNOWN_BLOB_LABEL_FORMAT = @"{%d-byte %@ blob}"; + (NSDictionary*)databaseExecuteSqlResponseToDictionary: (DatabaseExecuteSqlResponse*)response { - return @{}; + NSMutableArray* rows = [NSMutableArray array]; + if (response.values) { + for (NSArray* row in response.values) { + NSMutableArray* rowValues = [NSMutableArray array]; + for (id item in row) { + [rowValues addObject:[self objectAndTypeToFlipperObject:item]]; + } + [rows addObject:rowValues]; + } + } + + NSMutableDictionary* result = [NSMutableDictionary dictionaryWithDictionary:@{ + @"type" : response.type, + @"columns" : response.columns, + @"values" : rows, + @"affectedCount" : @(response.affectedCount) + }]; + + if (response.insertedId) { + result[@"insertedId"] = response.insertedId; + } + + return result; } + (NSDictionary*)objectAndTypeToFlipperObject:(id)object {