Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse timestamp columns in text format. Fixes vapor/mysql-nio#71 #72

Merged
merged 6 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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