diff options
3 files changed, 187 insertions, 50 deletions
diff --git a/Frameworks/PostgresKit/Source/FLXPostgresConnectionTypeHandling.m b/Frameworks/PostgresKit/Source/FLXPostgresConnectionTypeHandling.m index bd46e788..483519cf 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresConnectionTypeHandling.m +++ b/Frameworks/PostgresKit/Source/FLXPostgresConnectionTypeHandling.m @@ -22,6 +22,7 @@ #import "FLXPostgresConnectionTypeHandling.h" #import "FLXPostgresTypeStringHandler.h" #import "FLXPostgresTypeNumberHandler.h" +#import "FLXPostgresTypeDateTimeHandler.h" #import "FLXPostgresException.h" @implementation FLXPostgresConnection (FLXPostgresConnectionTypeHandling) @@ -38,7 +39,8 @@ } [self registerTypeHandler:[FLXPostgresTypeStringHandler class]]; - [self registerTypeHandler:[FLXPostgresTypeNumberHandler class]]; + [self registerTypeHandler:[FLXPostgresTypeNumberHandler class]]; + [self registerTypeHandler:[FLXPostgresTypeDateTimeHandler class]]; } /** diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.h b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.h index 154d364f..b83eba76 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.h +++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.h @@ -4,32 +4,29 @@ // FLXPostgresTypeDateTimeHandler.h // PostgresKit // -// Created by Stuart Connolly (stuconnolly.com) on September 1, 2012. -// Copyright (c) 2012 Stuart Connolly. All rights reserved. +// Copyright (c) 2008-2009 David Thorpe, djt@mutablelogic.com // -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. +// 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. + +@class FLXPostgresTypeNumberHandler; #import "FLXPostgresTypeHandler.h" -@interface FLXPostgresTypeDateTimeHandler : FLXPostgresTypeHandler <FLXPostgresTypeHandlerProtocol> +@interface FLXPostgresTypeDateTimeHandler : FLXPostgresTypeHandler <FLXPostgresTypeHandlerProtocol> +{ + FLXPostgresTypeNumberHandler *_numberHandler; +} @end diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m index 761e9e17..8f8ace87 100644 --- a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m +++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m @@ -4,42 +4,52 @@ // FLXPostgresTypeDateTimeHandler.m // PostgresKit // -// Created by Stuart Connolly (stuconnolly.com) on September 1, 2012. -// Copyright (c) 2012 Stuart Connolly. All rights reserved. +// Copyright (c) 2008-2009 David Thorpe, djt@mutablelogic.com // -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. +// 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 "FLXPostgresTypeDateTimeHandler.h" +#import "FLXPostgresTypeNumberHandler.h" +#import "FLXPostgresConnectionParameters.h" #import "FLXPostgresConnection.h" +#import "FLXPostgresConnectionTypeHandling.h" + +// Microseconds per second +#define USECS_PER_SEC 1000000 static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] = -{ - FLXPostgresOidAbsTime, +{ FLXPostgresOidDate, FLXPostgresOidTime, FLXPostgresOidTimeTZ, + FLXPostgresOidAbsTime, + FLXPostgresOidTimestamp, + FLXPostgresOidTimestampTZ, 0 }; +@interface FLXPostgresTypeDateTimeHandler () + +- (NSDate *)_postgresEpochDate; +- (NSDate *)_dateFromBytes:(const void *)bytes length:(NSUInteger)length; +- (NSDate *)_timeFromBytes:(const void *)bytes length:(NSUInteger)length; +- (NSDate *)_timestampFromBytes:(const void *)bytes length:(NSUInteger)length; +- (NSDate *)_dateByAddingComponents:(NSDateComponents *)components toDate:(NSDate *)date; + +@end + @implementation FLXPostgresTypeDateTimeHandler #pragma mark - @@ -71,8 +81,24 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] = { if (!bytes || !type) return nil; - // TODO: Imeplement me! - return nil; + if (!_numberHandler) { + _numberHandler = (FLXPostgresTypeNumberHandler *)[_connection typeHandlerForClass:[NSNumber class]]; + } + + switch (type) + { + case FLXPostgresOidDate: + return [self _dateFromBytes:bytes length:length]; + case FLXPostgresOidTime: + case FLXPostgresOidTimeTZ: + case FLXPostgresOidAbsTime: + return [self _timeFromBytes:bytes length:length]; + case FLXPostgresOidTimestamp: + case FLXPostgresOidTimestampTZ: + return [self _timestampFromBytes:bytes length:length]; + default: + return nil; + } } - (NSString *)quotedStringFromObject:(id)object @@ -83,4 +109,116 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] = return nil; } +#pragma mark - +#pragma mark Private API + +/** + * Returns the internal expoch date used by Postgres. + * + * @return The epoch date as an NSDate. + */ +- (NSDate *)_postgresEpochDate +{ + NSDateComponents *components = [[NSDateComponents alloc] init]; + + [components setDay:1]; + [components setMonth:1]; + [components setYear:2000]; + + NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + + NSDate *date = [gregorian dateFromComponents:components]; + + [components release]; + [gregorian release]; + + return date; +} + +/** + * Converts the supplied bytes representing a date to an NSDate instance. + * + * @param bytes The bytes to convert. + * @param length The number of bytes. + * + * @return The NSDate representation. + */ +- (NSDate *)_dateFromBytes:(const void *)bytes length:(NSUInteger)length +{ + NSDateComponents *components = [[NSDateComponents alloc] init]; + + [components setDay:[[_numberHandler integerObjectFromBytes:bytes length:length] integerValue]]; + + NSDate *date = [self _dateByAddingComponents:components toDate:[self _postgresEpochDate]]; + + [components release]; + + return date; +} + +/** + * Converts the supplied bytes representing the time to an NSDate instance. + * + * @param bytes The bytes to convert. + * @param length The number of bytes. + * + * @return The NSDate representation. + */ +- (NSDate *)_timeFromBytes:(const void *)bytes length:(NSUInteger)length +{ + NSNumber *time = [_numberHandler integerObjectFromBytes:bytes length:length]; + + return [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)[time doubleValue]]; +} + +/** + * Converts the supplied bytes representing a timestamp to an NSDate instance. + * + * @param bytes The bytes to convert. + * @param length The number of bytes. + * + * @return The NSDate representation. + */ +- (NSDate *)_timestampFromBytes:(const void *)bytes length:(NSUInteger)length +{ + NSDate *date = nil; + NSUInteger seconds = 0; + + if ([[[_connection parameters] valueForParameter:FLXPostgresParameterIntegerDateTimes] boolValue]) { + seconds = ([[_numberHandler integerObjectFromBytes:bytes length:length] doubleValue] / (double)USECS_PER_SEC); + } + else { + seconds = [_numberHandler float64FromBytes:bytes]; + } + + NSDateComponents *components = [[NSDateComponents alloc] init]; + + [components setSecond:seconds]; + + date = [self _dateByAddingComponents:components toDate:[self _postgresEpochDate]]; + + [components release]; + + return date; +} + +/** + * Returns the result of adding the supplied components to the supplied date. + * + * @param components The date components to add. + * @param date The date to add the components to. + * + * @return The result of the addition to the date. + */ +- (NSDate *)_dateByAddingComponents:(NSDateComponents *)components toDate:(NSDate *)date +{ + NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + + NSDate *newDate = [gregorian dateByAddingComponents:components toDate:date options:0]; + + [gregorian release]; + + return newDate; +} + @end |