From bc39e252aed0269716525a39c5f2e034f1d56c19 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 9 Sep 2012 12:08:23 +0000 Subject: Add support for network address types. --- .../PostgresKit.xcodeproj/project.pbxproj | 2 +- .../PostgresKit/Source/FLXPostgresConnection.m | 2 +- Frameworks/PostgresKit/Source/FLXPostgresResult.m | 2 +- .../Source/FLXPostgresTypeDateTimeHandler.m | 8 +- .../Source/FLXPostgresTypeNumberHandler.m | 14 ++-- .../Source/FLXPostgresTypeStringHandler.m | 90 +++++++++++++++++++--- Frameworks/PostgresKit/Source/FLXPostgresTypes.h | 7 +- 7 files changed, 99 insertions(+), 26 deletions(-) (limited to 'Frameworks') diff --git a/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj b/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj index 3f992739..4b447687 100644 --- a/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj +++ b/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj @@ -62,7 +62,7 @@ isa = PBXContainerItemProxy; containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 8DC2EF4F0486A6940098B216 /* PostgresKit */; + remoteGlobalIDString = 8DC2EF4F0486A6940098B216; remoteInfo = PostgresKit; }; /* End PBXContainerItemProxy section */ diff --git a/Frameworks/PostgresKit/Source/FLXPostgresConnection.m b/Frameworks/PostgresKit/Source/FLXPostgresConnection.m index df00dc8e..4d6afbd8 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresConnection.m +++ b/Frameworks/PostgresKit/Source/FLXPostgresConnection.m @@ -344,7 +344,7 @@ static void _FLXPostgresConnectionNoticeProcessor(void *arg, const char *message PQsetNoticeProcessor(_connection, _FLXPostgresConnectionNoticeProcessor, self); // Register type extensions - if (PQinitTypes(_connection)) { + if (!PQinitTypes(_connection)) { NSLog(@"PostgresKit: Error: Failed to initialise type extensions. Connection might return unexpected results!"); } diff --git a/Frameworks/PostgresKit/Source/FLXPostgresResult.m b/Frameworks/PostgresKit/Source/FLXPostgresResult.m index 303533bb..2da1a78f 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresResult.m +++ b/Frameworks/PostgresKit/Source/FLXPostgresResult.m @@ -149,7 +149,7 @@ static NSString *FLXPostgresResultError = @"FLXPostgresResultError"; data = (type == FLXPostgresResultRowAsArray) ? [NSMutableArray arrayWithCapacity:_numberOfFields] : [NSMutableDictionary dictionaryWithCapacity:_numberOfFields]; - for (unsigned int i = 0; i < _numberOfFields; i++) + for (NSUInteger i = 0; i < _numberOfFields; i++) { id object = [self _objectForRow:(int)_row column:i]; diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m index 2dd4227c..64c6f04c 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m +++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m @@ -44,7 +44,7 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] = @interface FLXPostgresTypeDateTimeHandler () - (NSDate *)_dateFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column; -- (FLXPostgresTimeInterval *)_timeIntervalFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column; +- (id)_timeIntervalFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column; - (id)_timeFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column type:(FLXPostgresOid)type; - (id)_timestmpFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column type:(FLXPostgresOid)type; @@ -91,7 +91,7 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] = case FLXPostgresOidInterval: return [self _timeIntervalFromResult:result atRow:row column:column]; default: - return nil; + return [NSNull null]; } } @@ -131,11 +131,11 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] = * * @return The FLXPostgresTimeInterval representation. */ -- (FLXPostgresTimeInterval *)_timeIntervalFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column +- (id)_timeIntervalFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column { PGinterval interval; - if (!PQgetf(result, row, "%interval", column, &interval)) return nil; + if (!PQgetf(result, row, "%interval", column, &interval)) return [NSNull null]; return [FLXPostgresTimeInterval intervalWithPGInterval:&interval]; } diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m b/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m index f3342684..42db1b33 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m +++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m @@ -51,7 +51,7 @@ static FLXPostgresOid FLXPostgresTypeNumberTypes[] = #pragma mark - #pragma mark Integer -- (NSNumber *)_integerObjectFromBytes:(const void *)bytes length:(NSUInteger)length +- (id)_integerObjectFromBytes:(const void *)bytes length:(NSUInteger)length { switch (length) { @@ -63,7 +63,7 @@ static FLXPostgresOid FLXPostgresTypeNumberTypes[] = return [NSNumber numberWithLongLong:[self _int64FromBytes:bytes]]; } - return nil; + return [NSNull null]; } - (SInt16)_int16FromBytes:(const void *)bytes @@ -84,7 +84,7 @@ static FLXPostgresOid FLXPostgresTypeNumberTypes[] = #pragma mark - #pragma mark Floating Point -- (NSNumber *)_floatObjectFromBytes:(const void *)bytes length:(NSUInteger)length +- (id)_floatObjectFromBytes:(const void *)bytes length:(NSUInteger)length { switch (length) { @@ -94,7 +94,7 @@ static FLXPostgresOid FLXPostgresTypeNumberTypes[] = return [NSNumber numberWithDouble:[self _float64FromBytes:bytes]]; } - return nil; + return [NSNull null]; } - (Float32)_float32FromBytes:(const void *)bytes @@ -120,9 +120,9 @@ static FLXPostgresOid FLXPostgresTypeNumberTypes[] = #pragma mark - #pragma mark Boolean -- (NSNumber *)_booleanObjectFromBytes:(const void *)bytes length:(NSUInteger)length +- (id)_booleanObjectFromBytes:(const void *)bytes length:(NSUInteger)length { - if (length != 1) return nil; + if (length != 1) return [NSNull null]; return [NSNumber numberWithBool:*((const int8_t *)bytes) ? YES : NO]; } @@ -165,7 +165,7 @@ static FLXPostgresOid FLXPostgresTypeNumberTypes[] = case FLXPostgresOidBool: return [self _booleanObjectFromBytes:bytes length:length]; default: - return nil; + return [NSNull null]; } } diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeStringHandler.m b/Frameworks/PostgresKit/Source/FLXPostgresTypeStringHandler.m index 7d328aa1..26c0ba32 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresTypeStringHandler.m +++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeStringHandler.m @@ -23,6 +23,8 @@ #import "FLXPostgresTypeStringHandler.h" #import "FLXPostgresConnection.h" +#import + static FLXPostgresOid FLXPostgresTypeStringTypes[] = { FLXPostgresOidText, @@ -34,6 +36,8 @@ static FLXPostgresOid FLXPostgresTypeStringTypes[] = FLXPostgresOidUUID, FLXPostgresOidBit, FLXPostgresOidVarBit, + FLXPostgresOidInetAddr, + FLXPostgresOidCidrAddr, FLXPostgresOidMacAddr, FLXPostgresOidUnknown, 0 @@ -41,7 +45,9 @@ static FLXPostgresOid FLXPostgresTypeStringTypes[] = @interface FLXPostgresTypeStringHandler () -- (NSString *)_macAddressFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column; +- (id)_stringFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column; +- (id)_macAddressFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column; +- (id)_inetAddressFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column type:(FLXPostgresOid)type; @end @@ -68,21 +74,53 @@ static FLXPostgresOid FLXPostgresTypeStringTypes[] = - (id)objectFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column { - if (PQftype(result, column) == FLXPostgresOidMacAddr) { - return [self _macAddressFromResult:result atRow:row column:column]; - } + FLXPostgresOid type = PQftype(result, column); + switch (type) + { + case FLXPostgresOidMacAddr: + return [self _macAddressFromResult:result atRow:row column:column]; + case FLXPostgresOidInetAddr: + case FLXPostgresOidCidrAddr: + return [self _inetAddressFromResult:result atRow:row column:column type:type]; + case FLXPostgresOidText: + case FLXPostgresOidChar: + case FLXPostgresOidName: + case FLXPostgresOidNumeric: + case FLXPostgresOidVarChar: + case FLXPostgresOidXML: + case FLXPostgresOidUUID: + case FLXPostgresOidBit: + case FLXPostgresOidVarBit: + case FLXPostgresOidUnknown: + return [self _stringFromResult:result atRow:row column:column]; + default: + return [NSNull null]; + } +} + +#pragma mark - +#pragma mark Private API + +/** + * Converts a char value to a string. + * + * @param result The result to extract the value from. + * @param row The row to extract the value from. + * @param column The column to extract the value from. + * + * @return A string representation of the value. + */ +- (id)_stringFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column +{ const void *bytes = PQgetvalue(result, row, column); NSUInteger length = PQgetlength(result, row, column); - if (!bytes || !length) return nil; + if (!bytes || !length) return [NSNull null]; return [[[NSString alloc] initWithBytes:bytes length:length encoding:[_connection stringEncoding]] autorelease]; } -#pragma mark - -#pragma mark Private API - /** * Converts a MAC address value to a string. * @@ -92,13 +130,45 @@ static FLXPostgresOid FLXPostgresTypeStringTypes[] = * * @return A string representation of the MAC address. */ -- (NSString *)_macAddressFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column +- (id)_macAddressFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column { PGmacaddr address; - if (!PQgetf(result, row, "%macaddr", column, &address)) return nil; + if (!PQgetf(result, row, "%macaddr", column, &address)) return [NSNull null]; return [NSString stringWithFormat:@"%02d:%02d:%02d:%02d:%02d:%02d", address.a, address.b, address.c, address.d, address.e, address.f]; } +/** + * Converts a network address value to a string. + * + * @param result The result to extract the value from. + * @param row The row to extract the value from. + * @param column The column to extract the value from. + * @param type The type of the value to extract. + * + * @return A string representation of the network address. + */ +- (id)_inetAddressFromResult:(const PGresult *)result atRow:(unsigned int)row column:(unsigned int)column type:(FLXPostgresOid)type +{ + PGinet inet; + + if (!PQgetf(result, row, type == FLXPostgresOidInetAddr ? "%inet" : "%cidr", column, &inet)) return [NSNull null]; + + char ip[80]; + struct sockaddr *sa = (struct sockaddr *)inet.sa_buf; + + NSUInteger success = getnameinfo(sa, inet.sa_buf_len, ip, sizeof(ip), NULL, 0, NI_NUMERICHOST); + + if (success != 0) { + const char *error = gai_strerror(success); + + NSLog(@"PostgresKit: Error: Failed to convert IP address to string representation (%s)", error); + + return [NSNull null]; + } + + return [NSString stringWithUTF8String:ip]; +} + @end diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypes.h b/Frameworks/PostgresKit/Source/FLXPostgresTypes.h index 625a7083..0a382950 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresTypes.h +++ b/Frameworks/PostgresKit/Source/FLXPostgresTypes.h @@ -57,6 +57,9 @@ enum FLXPostgresOidBox = 603, // Currently not supported FLXPostgresOidPolygon = 604, // Currently not supported + // Network + FLXPostgresOidCidrAddr = 650, // StringHandler => NSString + // Float FLXPostgresOidFloat4 = 700, // NumberHandler => NSNumber FLXPostgresOidFloat8 = 701, // NumberHandler => NSNumber @@ -74,8 +77,8 @@ enum FLXPostgresOidMoney = 790, // NumberHandler => NSNumber // Network - FLXPostgresOidMacAddr = 829, // StringHandler => NSString - FLXPostgresOidIPAddr = 869, // + FLXPostgresOidMacAddr = 829, // StringHandler => NSString + FLXPostgresOidInetAddr = 869, // StringHandler => NSString // Arrays FLXPostgresOidArrayBool = 1000, // Currently not supported -- cgit v1.2.3