aboutsummaryrefslogtreecommitdiffstats
path: root/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m
diff options
context:
space:
mode:
authorstuconnolly <stuart02@gmail.com>2012-09-03 10:22:17 +0000
committerstuconnolly <stuart02@gmail.com>2012-09-03 10:22:17 +0000
commite124a1d0fb576c311a6ac601b1c08e6ce51bcd30 (patch)
tree5a3350fc75bcad1f5c8d07f8a66ea53b0a07805f /Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m
parentd4e8474b3437771fd6891def8324981d82186a88 (diff)
downloadsequelpro-e124a1d0fb576c311a6ac601b1c08e6ce51bcd30.tar.gz
sequelpro-e124a1d0fb576c311a6ac601b1c08e6ce51bcd30.tar.bz2
sequelpro-e124a1d0fb576c311a6ac601b1c08e6ce51bcd30.zip
Initial commit of PostgresKit, our new Postgres framework as a start towards adding PostgreSQL support to Sequel Pro.
Note, that the framerwork is by no means feature complete and in it's current state has quite a few limitations: - No support for Postgres' asynchronous query API - Only supports the very basic data types (char/text and numerics) - No support (outide of libpq) for re-establishing dropped connections Current feature support includes: - Basic connection handling - Query execution - Prepared statement execution - Encoding support similar to SPMySQL's
Diffstat (limited to 'Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m')
-rw-r--r--Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m325
1 files changed, 325 insertions, 0 deletions
diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m b/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m
new file mode 100644
index 00000000..0c75e282
--- /dev/null
+++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m
@@ -0,0 +1,325 @@
+//
+// $Id$
+//
+// FLXPostgresTypeNumberHandler.m
+// PostgresKit
+//
+// Copyright (c) 2008-2009 David Thorpe, djt@mutablelogic.com
+//
+// Forked by the Sequel Pro Team on July 22, 2012.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#import "FLXPostgresTypeNumberHandler.h"
+#import "FLXPostgresTypes.h"
+
+static FLXPostgresOid FLXPostgresTypeNumberTypes[] =
+{
+ FLXPostgresOidInt8,
+ FLXPostgresOidInt2,
+ FLXPostgresOidInt4,
+ FLXPostgresOidFloat4,
+ FLXPostgresOidFloat8,
+ FLXPostgresOidBool,
+ 0
+};
+
+@implementation FLXPostgresTypeNumberHandler
+
+#pragma mark -
+#pragma mark Integer & Unsigned Integer
+
+- (SInt16)int16FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ return EndianS16_BtoN(*((SInt16 *)bytes));
+}
+
+- (SInt32)int32FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ return EndianS32_BtoN(*((SInt32 *)bytes));
+}
+
+- (SInt64)int64FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ return EndianS64_BtoN(*((SInt64 *)bytes));
+}
+
+- (UInt16)unsignedInt16FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ return EndianU16_BtoN(*((UInt16 *)bytes));
+}
+
+- (UInt32)unsignedInt32FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ return EndianU32_BtoN(*((UInt32 *)bytes));
+}
+
+- (UInt64)unsignedInt64FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ return EndianU64_BtoN(*((UInt64 *)bytes));
+}
+
+- (NSNumber *)integerObjectFromBytes:(const void *)bytes length:(NSUInteger)length
+{
+ if (!bytes) return nil;
+
+ switch (length)
+ {
+ case 2:
+ return [NSNumber numberWithShort:[self int16FromBytes:bytes]];
+ case 4:
+ return [NSNumber numberWithInteger:[self int32FromBytes:bytes]];
+ case 8:
+ return [NSNumber numberWithLongLong:[self int64FromBytes:bytes]];
+ }
+
+ return nil;
+}
+
+- (NSNumber *)unsignedIntegerObjectFromBytes:(const void *)bytes length:(NSUInteger)length
+{
+ if (!bytes) return nil;
+
+ switch (length)
+ {
+ case 2:
+ return [NSNumber numberWithUnsignedShort:[self unsignedInt16FromBytes:bytes]];
+ case 4:
+ return [NSNumber numberWithUnsignedInteger:[self unsignedInt32FromBytes:bytes]];
+ case 8:
+ return [NSNumber numberWithUnsignedLongLong:[self unsignedInt64FromBytes:bytes]];
+ }
+
+ return nil;
+}
+
+- (NSData *)remoteDataFromInt64:(SInt64)value
+{
+ if (sizeof(SInt64) != 8) return nil;
+
+ value = EndianS64_NtoB(value);
+
+ return [NSData dataWithBytes:&value length:sizeof(value)];
+}
+
+- (NSData *)remoteDataFromInt32:(SInt32)value
+{
+ if (sizeof(SInt32) != 4) return nil;
+
+ value = EndianS32_NtoB(value);
+
+ return [NSData dataWithBytes:&value length:sizeof(value)];
+}
+
+- (NSData *)remoteDataFromInt16:(SInt16)value
+{
+ if (sizeof(SInt16) != 2) return nil;
+
+ value = EndianS16_NtoB(value);
+
+ return [NSData dataWithBytes:&value length:sizeof(value)];
+}
+
+#pragma mark -
+#pragma mark Floating Point
+
+- (Float32)float32FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ union { Float32 r; UInt32 i; } u32;
+
+ u32.r = *((Float32 *)bytes);
+ u32.i = CFSwapInt32HostToBig(u32.i);
+
+ return u32.r;
+}
+
+- (Float64)float64FromBytes:(const void *)bytes
+{
+ if (!bytes) return 0;
+
+ union { Float64 r; UInt64 i; } u64;
+
+ u64.r = *((Float64 *)bytes);
+ u64.i = CFSwapInt64HostToBig(u64.i);
+
+ return u64.r;
+}
+
+- (NSNumber *)realObjectFromBytes:(const void *)bytes length:(NSUInteger)length
+{
+ switch (length)
+ {
+ case 4:
+ return [NSNumber numberWithFloat:[self float32FromBytes:bytes]];
+ case 8:
+ return [NSNumber numberWithDouble:[self float64FromBytes:bytes]];
+ }
+
+ return nil;
+}
+
+
+- (NSData *)remoteDataFromFloat32:(Float32)value
+{
+ if (sizeof(Float32) != 4) return nil;
+
+ union { Float32 r; UInt32 i; } u32;
+
+ u32.r = value;
+ u32.i = CFSwapInt32HostToBig(u32.i);
+
+ return [NSData dataWithBytes:&u32 length:sizeof(u32)];
+}
+
+- (NSData *)remoteDataFromFloat64:(Float64)value
+{
+ if (sizeof(Float64) != 8) return nil;
+
+ union { Float64 r; UInt64 i; } u64;
+
+ u64.r = value;
+ u64.i = CFSwapInt64HostToBig(u64.i);
+
+ return [NSData dataWithBytes:&u64 length:sizeof(u64)];
+}
+
+#pragma mark -
+#pragma mark Boolean
+
+- (BOOL)booleanFromBytes:(const void *)bytes
+{
+ if (!bytes) return NO;
+
+ return (*((const int8_t *)bytes) ? YES : NO);
+}
+
+- (NSNumber *)booleanObjectFromBytes:(const void *)bytes length:(NSUInteger)length
+{
+ if (!bytes || length != 1) return nil;
+
+ return [NSNumber numberWithBool:[self booleanFromBytes:bytes]];
+}
+
+
+- (NSData *)remoteDataFromBoolean:(BOOL)value
+{
+ return [NSData dataWithBytes:&value length:1];
+}
+
+#pragma mark -
+#pragma mark Protocol Implementation
+
+- (FLXPostgresOid *)remoteTypes
+{
+ return FLXPostgresTypeNumberTypes;
+}
+
+- (Class)nativeClass
+{
+ return [NSNumber class];
+}
+
+- (NSArray *)classAliases
+{
+ return nil;
+}
+
+- (NSData *)remoteDataFromObject:(id)object type:(FLXPostgresOid *)type
+{
+ if (!object || !type || ![object isKindOfClass:[NSNumber class]]) return nil;
+
+ NSNumber *number = (NSNumber *)object;
+
+ const char *objectType = [number objCType];
+
+ switch (objectType[0])
+ {
+ case 'c':
+ case 'C':
+ case 'B': // Boolean
+ (*type) = FLXPostgresOidBool;
+ return [self remoteDataFromBoolean:[(NSNumber *)object boolValue]];
+ case 'i': // Integer
+ case 'l': // Long
+ case 'S': // Unsigned short
+ (*type) = FLXPostgresOidInt4;
+ return [self remoteDataFromInt32:[(NSNumber *)object shortValue]];
+ case 's':
+ (*type) = FLXPostgresOidInt2;
+ return [self remoteDataFromInt16:[(NSNumber *)object shortValue]];
+ case 'q': // Long long
+ case 'Q': // Unsigned long long
+ case 'I': // Unsigned integer
+ case 'L': // Unsigned long
+ (*type) = FLXPostgresOidInt8;
+ return [self remoteDataFromInt64:[(NSNumber *)object longLongValue]];
+ case 'f': // Float
+ (*type) = FLXPostgresOidFloat4;
+ return [self remoteDataFromFloat32:[(NSNumber *)object floatValue]];
+ case 'd': // Double
+ (*type) = FLXPostgresOidFloat8;
+ return [self remoteDataFromFloat64:[(NSNumber *)object doubleValue]];
+ }
+
+ return nil;
+}
+
+- (id)objectFromRemoteData:(const void *)bytes length:(NSUInteger)length type:(FLXPostgresOid)type
+{
+ if (!bytes || !length || !type) return nil;
+
+ switch (type)
+ {
+ case FLXPostgresOidInt8:
+ case FLXPostgresOidInt2:
+ case FLXPostgresOidInt4:
+ return [self integerObjectFromBytes:bytes length:length];
+ case FLXPostgresOidFloat4:
+ case FLXPostgresOidFloat8:
+ return [self realObjectFromBytes:bytes length:length];
+ case FLXPostgresOidBool:
+ return [self booleanObjectFromBytes:bytes length:length];
+ default:
+ return nil;
+ }
+}
+
+- (NSString *)quotedStringFromObject:(id)object
+{
+ if (!object || ![object isKindOfClass:[NSNumber class]]) return nil;
+
+ const char *type = [object objCType];
+
+ if (type[0] == 'c' || type[0] == 'C' || type[0] == 'B') {
+ return ([(NSNumber *)object boolValue] ? @"true" : @"false");
+ }
+ else {
+ return [(NSNumber *)object stringValue];
+ }
+}
+
+@end