diff --git a/Sources/MySQLNIO/MySQLData.swift b/Sources/MySQLNIO/MySQLData.swift index 0fef1c9..d6c0461 100644 --- a/Sources/MySQLNIO/MySQLData.swift +++ b/Sources/MySQLNIO/MySQLData.swift @@ -429,10 +429,16 @@ public struct MySQLData: CustomStringConvertible, ExpressibleByStringLiteral, Ex guard var buffer = self.buffer else { return nil } - switch self.type { - case .timestamp, .datetime, .date, .time: - return buffer.readMySQLTime() - default: return nil + switch self.format { + case .binary: + switch self.type { + case .timestamp, .datetime, .date, .time: + return buffer.readMySQLTime() + default: return nil + } + case .text: + guard let s = buffer.readString(length: buffer.readableBytes) else { return nil } + return MySQLTime(s) } } diff --git a/Sources/MySQLNIO/MySQLTime.swift b/Sources/MySQLNIO/MySQLTime.swift index d2303eb..985c9f4 100644 --- a/Sources/MySQLNIO/MySQLTime.swift +++ b/Sources/MySQLNIO/MySQLTime.swift @@ -50,7 +50,7 @@ public struct MySQLTime: Equatable, MySQLDataConvertible { self.microsecond = microsecond } - /// Creates a new `MySQLTime` from a Swift Date using current calendar and GMT timezone. + /// Creates a new ``MySQLTime`` from a Swift ``Date`` using current calendar and GMT timezone. public init(date: Date) { // let comps = Calendar.current.dateComponents(in: .gmt, from: date) var rawtime = Int(date.timeIntervalSince1970) @@ -71,6 +71,24 @@ public struct MySQLTime: Equatable, MySQLDataConvertible { ) } + /// Parse a new ``MySQLTime`` from a ``String`` in `"yyyy-MM-dd hh:mm:ss"` format. + public init?(_ string: String) { + let parts = string.split { c in + ":- ".contains(c) + } + guard parts.count >= 6, + let year = UInt16(parts[0]), + let month = UInt16(parts[1]), + let day = UInt16(parts[2]), + let hour = UInt16(parts[3]), + let minute = UInt16(parts[4]), + let second = UInt16(parts[5]) + else { + return nil + } + self.init(year: year, month: month, day: day, hour: hour, minute: minute, second: second) + } + /// See ``MySQLDataConvertible/init(mysqlData:)``. public init?(mysqlData: MySQLData) { guard let time = mysqlData.time else { diff --git a/Tests/MySQLNIOTests/MySQLNIOTests.swift b/Tests/MySQLNIOTests/MySQLNIOTests.swift index a467975..5a52ddd 100644 --- a/Tests/MySQLNIOTests/MySQLNIOTests.swift +++ b/Tests/MySQLNIOTests/MySQLNIOTests.swift @@ -621,6 +621,16 @@ final class MySQLNIOTests: XCTestCase { XCTAssertEqual(time.date, nil) } + func testTextMySQLTimeParse() throws { + let conn = try MySQLConnection.test(on: self.eventLoop).wait() + defer { try! conn.close().wait() } + + // The text protocol returns timestamp columns in text format. + // Ensure these can be converted to MySQLTime without error. + let rows = try conn.simpleQuery("SELECT CURRENT_TIMESTAMP() AS foo").wait() + XCTAssertNotNil(rows[0].column("foo")?.time) + } + func testNull() throws { let conn = try MySQLConnection.test(on: self.eventLoop).wait() defer { try! conn.close().wait() }