Skip to content

Commit

Permalink
Parse timestamp columns in text format. Fixes #71 (#72)
Browse files Browse the repository at this point in the history
* Parse timestamp columns in text format. Fixes #71
  • Loading branch information
samalone committed May 9, 2023
1 parent 12f282b commit 4d2aa38
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
14 changes: 10 additions & 4 deletions Sources/MySQLNIO/MySQLData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
20 changes: 19 additions & 1 deletion Sources/MySQLNIO/MySQLTime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 {
Expand Down
10 changes: 10 additions & 0 deletions Tests/MySQLNIOTests/MySQLNIOTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
Expand Down

0 comments on commit 4d2aa38

Please sign in to comment.