aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstuconnolly <stuart02@gmail.com>2012-09-08 10:45:57 +0000
committerstuconnolly <stuart02@gmail.com>2012-09-08 10:45:57 +0000
commitf7df6d3700bac8181e2258a9df28a32153124c46 (patch)
treedf91350bbb69e167148d16a76f584ccccbd88a66
parent66f9f09721647b635e4095c865653b8008c9552e (diff)
downloadsequelpro-f7df6d3700bac8181e2258a9df28a32153124c46.tar.gz
sequelpro-f7df6d3700bac8181e2258a9df28a32153124c46.tar.bz2
sequelpro-f7df6d3700bac8181e2258a9df28a32153124c46.zip
Add native timezone type support.
-rw-r--r--Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj16
-rw-r--r--Frameworks/PostgresKit/Source/FLXPostgresConnectionPrivateAPI.h3
-rw-r--r--Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m2
-rw-r--r--Frameworks/PostgresKit/Source/FLXPostgresResult.m2
-rw-r--r--Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m48
-rw-r--r--Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m2
-rw-r--r--Frameworks/PostgresKit/Source/FLXTimeTZ.h62
-rw-r--r--Frameworks/PostgresKit/Source/FLXTimeTZ.m84
8 files changed, 197 insertions, 22 deletions
diff --git a/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj b/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj
index 9749dc39..fa760468 100644
--- a/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj
+++ b/Frameworks/PostgresKit/PostgresKit.xcodeproj/project.pbxproj
@@ -10,6 +10,8 @@
170465CE15C2960F00DC5BE5 /* FLXPostgresTypeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 170465CC15C2960F00DC5BE5 /* FLXPostgresTypeHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
170465CF15C2960F00DC5BE5 /* FLXPostgresTypeHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 170465CD15C2960F00DC5BE5 /* FLXPostgresTypeHandler.m */; };
1724C9B815F9ED8600AB2291 /* libpqtypes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1724C9B715F9ED8600AB2291 /* libpqtypes.a */; };
+ 1724CC9215FB4CC200AB2291 /* FLXTimeTZ.h in Headers */ = {isa = PBXBuildFile; fileRef = 1724CC9015FB4CC200AB2291 /* FLXTimeTZ.h */; };
+ 1724CC9315FB4CC200AB2291 /* FLXTimeTZ.m in Sources */ = {isa = PBXBuildFile; fileRef = 1724CC9115FB4CC200AB2291 /* FLXTimeTZ.m */; };
1731F02B15EE09E000D973EB /* FLXPostgresConnectionParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 1731F02915EE09E000D973EB /* FLXPostgresConnectionParameters.h */; };
1731F02C15EE09E000D973EB /* FLXPostgresConnectionParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 1731F02A15EE09E000D973EB /* FLXPostgresConnectionParameters.m */; };
1731F10815F1A52B00D973EB /* FLXPostgresTypeDateTimeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 1731F10615F1A52B00D973EB /* FLXPostgresTypeDateTimeHandler.h */; };
@@ -56,6 +58,8 @@
170465CD15C2960F00DC5BE5 /* FLXPostgresTypeHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLXPostgresTypeHandler.m; sourceTree = "<group>"; };
1724C9B715F9ED8600AB2291 /* libpqtypes.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libpqtypes.a; sourceTree = "<group>"; };
1724CA3B15F9EE7300AB2291 /* libpqtypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libpqtypes.h; sourceTree = "<group>"; };
+ 1724CC9015FB4CC200AB2291 /* FLXTimeTZ.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLXTimeTZ.h; sourceTree = "<group>"; };
+ 1724CC9115FB4CC200AB2291 /* FLXTimeTZ.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLXTimeTZ.m; sourceTree = "<group>"; };
1731F02915EE09E000D973EB /* FLXPostgresConnectionParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLXPostgresConnectionParameters.h; sourceTree = "<group>"; };
1731F02A15EE09E000D973EB /* FLXPostgresConnectionParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLXPostgresConnectionParameters.m; sourceTree = "<group>"; };
1731F10615F1A52B00D973EB /* FLXPostgresTypeDateTimeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLXPostgresTypeDateTimeHandler.h; sourceTree = "<group>"; };
@@ -192,6 +196,15 @@
path = lib;
sourceTree = "<group>";
};
+ 1724CC8715FB4BF400AB2291 /* Domain */ = {
+ isa = PBXGroup;
+ children = (
+ 1724CC9015FB4CC200AB2291 /* FLXTimeTZ.h */,
+ 1724CC9115FB4CC200AB2291 /* FLXTimeTZ.m */,
+ );
+ name = Domain;
+ sourceTree = "<group>";
+ };
1731F50415F369E400D973EB /* Query */ = {
isa = PBXGroup;
children = (
@@ -257,6 +270,7 @@
children = (
173D4F5615BAD3030007F267 /* FLXPostgresTypes.h */,
173D4EA015BAB2A80007F267 /* FLXPostgresTypeHandlerProtocol.h */,
+ 1724CC8715FB4BF400AB2291 /* Domain */,
17F5B62215C7D1DA006DA689 /* Handlers */,
);
name = Types;
@@ -355,6 +369,7 @@
1731F02B15EE09E000D973EB /* FLXPostgresConnectionParameters.h in Headers */,
1731F10815F1A52B00D973EB /* FLXPostgresTypeDateTimeHandler.h in Headers */,
1731F52E15F48BA500D973EB /* FLXPostgresError.h in Headers */,
+ 1724CC9215FB4CC200AB2291 /* FLXTimeTZ.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -425,6 +440,7 @@
1731F02C15EE09E000D973EB /* FLXPostgresConnectionParameters.m in Sources */,
1731F10915F1A52B00D973EB /* FLXPostgresTypeDateTimeHandler.m in Sources */,
1731F52F15F48BA500D973EB /* FLXPostgresError.m in Sources */,
+ 1724CC9315FB4CC200AB2291 /* FLXTimeTZ.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Frameworks/PostgresKit/Source/FLXPostgresConnectionPrivateAPI.h b/Frameworks/PostgresKit/Source/FLXPostgresConnectionPrivateAPI.h
index 53bcf4ee..8f0e6a6e 100644
--- a/Frameworks/PostgresKit/Source/FLXPostgresConnectionPrivateAPI.h
+++ b/Frameworks/PostgresKit/Source/FLXPostgresConnectionPrivateAPI.h
@@ -25,13 +25,12 @@
@interface FLXPostgresConnection (FLXPostgresConnectionPrivateAPI)
- (PGconn *)postgresConnection;
-- (void)_createConnectionParameters;
@end
@interface FLXPostgresConnection (FLXPostgresConnectionQueryPreparationPrivateAPI)
-- (BOOL)_prepare:(FLXPostgresStatement *)statement num:(int)paramNum types:(FLXPostgresOid *)paramTypes;
+- (BOOL)_prepare:(FLXPostgresStatement *)statement num:(NSInteger)paramNum types:(FLXPostgresOid *)paramTypes;
@end
diff --git a/Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m b/Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m
index 679237d1..deeefc1a 100644
--- a/Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m
+++ b/Frameworks/PostgresKit/Source/FLXPostgresConnectionQueryPreparation.m
@@ -80,7 +80,7 @@
*
* @return A BOOL indicating succes. Returns NO if there's no statement, statement name or current connection.
*/
-- (BOOL)_prepare:(FLXPostgresStatement *)statement num:(int)paramNum types:(FLXPostgresOid *)paramTypes
+- (BOOL)_prepare:(FLXPostgresStatement *)statement num:(NSInteger)paramNum types:(FLXPostgresOid *)paramTypes
{
if (!statement || ![statement name] || ![self isConnected]) return NO;
diff --git a/Frameworks/PostgresKit/Source/FLXPostgresResult.m b/Frameworks/PostgresKit/Source/FLXPostgresResult.m
index 7136b819..303533bb 100644
--- a/Frameworks/PostgresKit/Source/FLXPostgresResult.m
+++ b/Frameworks/PostgresKit/Source/FLXPostgresResult.m
@@ -248,7 +248,7 @@ static NSString *FLXPostgresResultError = @"FLXPostgresResultError";
{
PQclear(_result);
- for (unsigned int i = 0; i < _numberOfFields; i++) [_fields[i] release];
+ for (NSUInteger i = 0; i < _numberOfFields; i++) [_fields[i] release];
free(_fields);
free(_typeHandlers);
diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m
index 1494478c..c60c1eb9 100644
--- a/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m
+++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeDateTimeHandler.m
@@ -25,6 +25,7 @@
#import "FLXPostgresConnectionParameters.h"
#import "FLXPostgresConnection.h"
#import "FLXPostgresConnectionTypeHandling.h"
+#import "FLXTimeTZ.h"
static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] =
{
@@ -40,8 +41,8 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] =
@interface FLXPostgresTypeDateTimeHandler ()
- (NSDate *)_dateFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column;
-- (NSDate *)_timeFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column;
-- (NSDate *)_timestmpFromResult:(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;
- (NSDate *)_dateFromComponents:(NSDateComponents *)components;
@@ -78,10 +79,10 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] =
case FLXPostgresOidTime:
case FLXPostgresOidTimeTZ:
case FLXPostgresOidAbsTime:
- return [self _timeFromResult:result atRow:row column:column];
+ return [self _timeFromResult:result atRow:row column:column type:type];
case FLXPostgresOidTimestamp:
case FLXPostgresOidTimestampTZ:
- return [self _timestmpFromResult:result atRow:row column:column];
+ return [self _timestmpFromResult:result atRow:row column:column type:type];
default:
return nil;
}
@@ -115,21 +116,24 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] =
}
/**
- * Returns an NSDate created from a time value.
+ * Returns a native object created from a time value.
*
* @note The date part should be ignored as it's set to a default value.
*
* @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.
+ * @type type The type to be converted from (handles times and times with a time zone).
*
- * @return The NSDate representation.
+ * @return The object representation.
*/
-- (NSDate *)_timeFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column
+- (id)_timeFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column type:(FLXPostgresOid)type
{
PGtime time;
- PQgetf(result, row, "%time", column, &time);
+ BOOL hasTimeZone = type == FLXPostgresOidTimeTZ;
+
+ PQgetf(result, row, hasTimeZone ? "%timetz" : "%time", column, &time);
NSDateComponents *components = [[NSDateComponents alloc] init];
@@ -142,29 +146,39 @@ static FLXPostgresOid FLXPostgresTypeDateTimeTypes[] =
[components setMinute:time.min];
[components setSecond:time.sec];
- // TODO: handle timezone
-
- return [self _dateFromComponents:components];
+ NSDate *date = [self _dateFromComponents:components];
+
+ return hasTimeZone ? [FLXTimeTZ timeWithDate:date timeZoneGMTOffset:time.gmtoff] : date;
}
/**
- * Returns an NSDate created from a timestamp value.
+ * Returns a native object created from a timestamp value.
*
* @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.
+ * @type type The type to be converted from (handles timestamps and timestamps with a time zone).
*
- * @return The NSDate representation.
+ * @return The object representation.
*/
-- (NSDate *)_timestmpFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column
+- (id)_timestmpFromResult:(const PGresult *)result atRow:(NSUInteger)row column:(NSUInteger)column type:(FLXPostgresOid)type
{
PGtimestamp timestamp;
- PQgetf(result, row, "%timestamp", column, &timestamp);
+ BOOL hasTimeZone = type == FLXPostgresOidTimestampTZ;
+
+ PQgetf(result, row, hasTimeZone ? "%timstamptz" : "%timestamp", column, &timestamp);
+
+ FLXTimeTZ *timestampTZ = nil;
+ NSDate *date = [NSDate dateWithTimeIntervalSince1970:timestamp.epoch];
- // TODO: handle timezone
+ if (hasTimeZone) {
+ timestampTZ = [FLXTimeTZ timeWithDate:date timeZoneGMTOffset:timestamp.time.gmtoff];
+
+ [timestampTZ setHasDate:YES];
+ }
- return [NSDate dateWithTimeIntervalSince1970:timestamp.epoch];
+ return hasTimeZone ? timestampTZ : date;
}
/**
diff --git a/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m b/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m
index 2f0fc2ad..5ea07047 100644
--- a/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m
+++ b/Frameworks/PostgresKit/Source/FLXPostgresTypeNumberHandler.m
@@ -47,7 +47,7 @@ static FLXPostgresOid FLXPostgresTypeNumberTypes[] =
@implementation FLXPostgresTypeNumberHandler
#pragma mark -
-#pragma mark Integer & Unsigned Integer
+#pragma mark Integer
- (NSNumber *)_integerObjectFromBytes:(const void *)bytes length:(NSUInteger)length
{
diff --git a/Frameworks/PostgresKit/Source/FLXTimeTZ.h b/Frameworks/PostgresKit/Source/FLXTimeTZ.h
new file mode 100644
index 00000000..a24fc2cf
--- /dev/null
+++ b/Frameworks/PostgresKit/Source/FLXTimeTZ.h
@@ -0,0 +1,62 @@
+//
+// $Id$
+//
+// FLXTimeTZ.h
+// PostgresKit
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 8, 2012.
+// Copyright (c) 2012 Stuart Connolly. All rights reserved.
+//
+// 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.
+
+/**
+ * @class FLXTimeTZ FLXTimeTZ.h
+ *
+ * @author Stuart Connolly http://stuconnolly.com
+ *
+ * Simple wrapper to represet a time or timestamp with an associated time zone.
+ */
+@interface FLXTimeTZ : NSObject
+{
+ BOOL _hasDate;
+
+ NSDate *_date;
+ NSTimeZone *_timeZone;
+}
+
+@property (readwrite, assign) BOOL hasDate;
+
+/**
+ * @property date The date instance that holds the time.
+ */
+@property (readonly) NSDate *date;
+
+/**
+ * @property timeZone The time zone of the associated time.
+ */
+@property (readonly) NSTimeZone *timeZone;
+
++ (FLXTimeTZ *)timeWithDate:(NSDate *)date timeZoneGMTOffset:(NSUInteger)offset;
+
+- (id)initWithDate:(NSDate *)date timeZoneGMTOffset:(NSUInteger)offset;
+
+@end
diff --git a/Frameworks/PostgresKit/Source/FLXTimeTZ.m b/Frameworks/PostgresKit/Source/FLXTimeTZ.m
new file mode 100644
index 00000000..48c97aa9
--- /dev/null
+++ b/Frameworks/PostgresKit/Source/FLXTimeTZ.m
@@ -0,0 +1,84 @@
+//
+// $Id$
+//
+// FLXTimeTZ.m
+// PostgresKit
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 8, 2012.
+// Copyright (c) 2012 Stuart Connolly. All rights reserved.
+//
+// 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.
+
+#import "FLXTimeTZ.h"
+
+@implementation FLXTimeTZ
+
+@synthesize hasDate = _hasDate;
+@synthesize date = _date;
+@synthesize timeZone = _timeZone;
+
+- (id)init
+{
+ return [self initWithDate:[NSDate date] timeZoneGMTOffset:[[NSTimeZone systemTimeZone] secondsFromGMT]];
+}
+
++ (FLXTimeTZ *)timeWithDate:(NSDate *)date timeZoneGMTOffset:(NSUInteger)offset
+{
+ return [[[FLXTimeTZ alloc] initWithDate:date timeZoneGMTOffset:offset] autorelease];
+}
+
+/**
+ * Initialise a FLXTimeTZ with the supplied date and GMT offset.
+ *
+ * @param date The date to use.
+ * @param offset The GMT offset in seconds that the associated time zone is.
+ *
+ * @return The initialised instance.
+ */
+- (id)initWithDate:(NSDate *)date timeZoneGMTOffset:(NSUInteger)offset
+{
+ if ((self = [super init])) {
+ _date = date;
+ _hasDate = NO;
+ _timeZone = [NSTimeZone timeZoneForSecondsFromGMT:offset];
+ }
+
+ return self;
+}
+
+#pragma mark -
+
+- (NSString *)description
+{
+ NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
+
+ [formatter setDateStyle:_hasDate ? NSDateFormatterMediumStyle : NSDateFormatterNoStyle];
+ [formatter setTimeStyle:NSDateFormatterMediumStyle];
+
+ NSString *output = [formatter stringFromDate:_date];
+
+ [formatter release];
+
+ return [NSString stringWithFormat:@"%@ %@", output, [_timeZone abbreviation]];
+}
+
+@end