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

Add Codable support to DatabaseDateComponents #766

Merged
merged 3 commits into from
Apr 20, 2020
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
28 changes: 27 additions & 1 deletion GRDB/Core/Support/Foundation/DatabaseDateComponents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SQLite3
#endif

/// DatabaseDateComponents reads and stores DateComponents in the database.
public struct DatabaseDateComponents: DatabaseValueConvertible, StatementColumnConvertible {
public struct DatabaseDateComponents: DatabaseValueConvertible, StatementColumnConvertible, Codable {

/// The available formats for reading and storing date components.
public enum Format: String {
Expand Down Expand Up @@ -159,4 +159,30 @@ public struct DatabaseDateComponents: DatabaseValueConvertible, StatementColumnC

return SQLiteDateParser().components(from: string)
}

// MARK: - Codable adoption


/// Creates a new instance by decoding from the given decoder.
///
/// - parameters:
/// - decoder: The decoder to read data from.
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let stringValue = try container.decode(String.self)
guard let decodedValue = DatabaseDateComponents.fromDatabaseValue(stringValue.databaseValue) else {
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Unable to initialise databaseDateComponent")
}
self = decodedValue
}

/// Encodes this value into the given encoder.
///
/// - parameters:
/// - encoder: The encoder to write data to.
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(String.fromDatabaseValue(databaseValue)!)
}
}
23 changes: 23 additions & 0 deletions Tests/GRDBTests/FoundationDateComponentsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -506,4 +506,27 @@ class FoundationDateComponentsTests : GRDBTestCase {
let databaseDateComponents = DatabaseDateComponents.fromDatabaseValue("foo".databaseValue)
XCTAssertTrue(databaseDateComponents == nil)
}

func testJSONEncodingOfDatabaseDateComponents() {
let year = 2018
let month = 12
let day = 31
let dbDateComponents = DatabaseDateComponents(
DateComponents(year: year, month: month, day: day, hour: nil, minute: nil, second: nil, nanosecond: nil),
format: .YMD)
let encoded = try! JSONEncoder().encode(dbDateComponents)
XCTAssertEqual(String(data: encoded, encoding: .utf8)!, "\"\(year)-\(month)-\(day)\"")
}

func testJSONDecodingOfDatabaseDateComponents() {
let year = 2018
let month = 12
let day = 31
let dbDateComponents = DatabaseDateComponents(
DateComponents(year: year, month: month, day: day, hour: nil, minute: nil, second: nil, nanosecond: nil),
format: .YMD)
let json = "\"\(year)-\(month)-\(day)\"".data(using: .utf8)!
let decodedDatabaseDateComponents = try! JSONDecoder().decode(DatabaseDateComponents.self, from: json)
XCTAssertEqual(decodedDatabaseDateComponents.dateComponents, dbDateComponents.dateComponents)
}
}