Skip to content

Commit f2ead73

Browse files
committed
point string decode
1 parent a565178 commit f2ead73

File tree

3 files changed

+49
-17
lines changed

3 files changed

+49
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Foundation
2+
3+
extension Date: PostgreSQLDataCustomConvertible {
4+
/// See `PostgreSQLDataCustomConvertible.preferredDataType`
5+
public static var preferredDataType: PostgreSQLDataType? { return .timestamp }
6+
7+
/// See `PostgreSQLDataCustomConvertible.convertFromPostgreSQLData(_:)`
8+
public static func convertFromPostgreSQLData(_ data: PostgreSQLData) throws -> Date {
9+
guard let value = data.data else {
10+
throw PostgreSQLError(identifier: "data", reason: "Could not decode String from `null` data.")
11+
}
12+
switch data.format {
13+
case .text:
14+
switch data.type {
15+
case .timestamp: return try value.makeString().parseDate(format: "yyyy-MM-dd HH:mm:ss")
16+
case .date: return try value.makeString().parseDate(format: "yyyy-MM-dd")
17+
case .time: return try value.makeString().parseDate(format: "HH:mm:ss")
18+
default: throw PostgreSQLError(identifier: "date", reason: "Could not parse Date from text data type: \(data.type).")
19+
}
20+
case .binary: throw PostgreSQLError(identifier: "date", reason: "Could not parse Date from binary data type: \(data.type).")
21+
}
22+
}
23+
24+
/// See `PostgreSQLDataCustomConvertible.convertToPostgreSQLData()`
25+
public func convertToPostgreSQLData() throws -> PostgreSQLData {
26+
return PostgreSQLData(type: .timestamp, format: .text, data: Data(description.utf8))
27+
}
28+
}
29+
30+
extension String {
31+
/// Parses a Date from this string with the supplied date format.
32+
fileprivate func parseDate(format: String) throws -> Date {
33+
let formatter = DateFormatter()
34+
if contains(".") {
35+
formatter.dateFormat = format + ".SSSSSS"
36+
} else {
37+
formatter.dateFormat = format
38+
}
39+
formatter.timeZone = TimeZone(secondsFromGMT: 0)
40+
guard let date = formatter.date(from: self) else {
41+
throw PostgreSQLError(identifier: "date", reason: "Malformed date: \(self)")
42+
}
43+
return date
44+
}
45+
}

Sources/PostgreSQL/DataType/PostgreSQLDataType+Parse.swift

-16
Original file line numberDiff line numberDiff line change
@@ -97,21 +97,5 @@ extension PostgreSQLDataType {
9797

9898
/// MARK: String Helpers
9999

100-
extension String {
101-
/// Parses a Date from this string with the supplied date format.
102-
fileprivate func parseDate(format: String) throws -> Date {
103-
let formatter = DateFormatter()
104-
if contains(".") {
105-
formatter.dateFormat = format + ".SSSSSS"
106-
} else {
107-
formatter.dateFormat = format
108-
}
109-
formatter.timeZone = TimeZone(secondsFromGMT: 0)
110-
guard let date = formatter.date(from: self) else {
111-
throw PostgreSQLError(identifier: "date", reason: "Malformed date: \(self)")
112-
}
113-
return date
114-
}
115-
}
116100

117101

Tests/PostgreSQLTests/PostgreSQLConnectionTests.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ class PostgreSQLConnectionTests: XCTestCase {
118118
try XCTAssertEqual(row["text"]?.decode(String.self), "11")
119119
try XCTAssertEqual(row["bytea"]?.decode(Data.self), Data([0x31, 0x32]))
120120
try XCTAssertEqual(row["boolean"]?.decode(Bool.self), true)
121-
// try XCTAssertEqual(row["point"]?.decode(Int16.self), .point(x: 13.5, y: 14)) // FIXME: decode point?
121+
try XCTAssertNotNil(row["timestamp"]?.decode(Date.self))
122+
try XCTAssertNotNil(row["date"]?.decode(Date.self))
123+
try XCTAssertNotNil(row["time"]?.decode(Date.self))
124+
try XCTAssertEqual(row["point"]?.decode(String.self), "(13.5,14)")
122125
} else {
123126
XCTFail("query result count is: \(queryResult.count)")
124127
}

0 commit comments

Comments
 (0)