Implement executeSql command.
Reviewed By: lblasa Differential Revision: D48310925 fbshipit-source-id: 136b7f09a3a1b886111b6e3cb0e377b73b126e59
This commit is contained in:
committed by
Facebook GitHub Bot
parent
42fb6f09f7
commit
7ba548d6e7
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <objc/NSObjCRuntime.h>
|
||||
|
||||
@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
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "DatabaseExecuteSql.h"
|
||||
#include <objc/NSObjCRuntime.h>
|
||||
|
||||
@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
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
@class DatabaseGetTableStructureResponse;
|
||||
@class DatabaseGetTableInfoResponse;
|
||||
@class DatabaseGetTableDataResponse;
|
||||
@class DatabaseExecuteSqlResponse;
|
||||
|
||||
@protocol DatabaseDriver<NSObject>
|
||||
- (NSArray<id<DatabaseDescriptor>>*)getDatabases;
|
||||
@@ -32,4 +33,5 @@
|
||||
reverse:(BOOL)reverse
|
||||
start:(NSInteger)start
|
||||
count:(NSInteger)count;
|
||||
- (DatabaseExecuteSqlResponse*)executeSQL:(NSString*)sql;
|
||||
@end
|
||||
|
||||
@@ -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<FlipperResponder> responder){
|
||||
withBlock:^(NSDictionary* params, id<FlipperResponder> 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];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@@ -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<NSString*>* 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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user