ITADN

JSON columns with Date and/or Bool fail decoding

#163Openjanigro 创建于 2023-01-13
bug
J
janigrocommented
### Problem Description When trying to decode a query that has a JSON column with booleans and/or date values, it fails with an error. Consider the following minimal example: ```swift struct MyContent: Content { let options: Options struct Options: Codable { let isEnabled: Bool let due: Date } } let query: SQLQueryString = "SELECT JSON_OBJECT('isEnabled', 1, 'due', NOW()) options" let results = try await db.raw(query).first(decoding: MyContent.self) ``` Running this code will produce: ``` Value of type 'Bool' required for key 'isEnabled'. ``` if we change the `Bool` to `Int`, we now get an error because of the `Date` value: ``` "Value of type 'Double' required for key 'due'. ``` The second error can be omitted by changing the type in the `due` property, from `Date` to `String` ### Expected Behavior Not sure if this is a bug report, or a feature request. But ideally, Fluent should be able to decode `Bool` and `Date` types. Or maybe I'm missing something obvious of why this is not the case? ### Workaround In the meantime, I'm implementing `Econdable.init(from decoder: Decoder)` to workaround the problem: ```swift struct MyContent: Content { let options: Options struct Options: Codable { let isEnabled: Bool let due: Date init(from decoder: Decoder) throws { let container: KeyedDecodingContainer<CodingKeys> = try decoder.container(keyedBy: CodingKeys.self) self.isEnabled = (try container.decode(Int.self, forKey: CodingKeys.isEnabled) != 0) let d = try container.decode(String.self, forKey: CodingKeys.due) let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSSSS" formatter.timeZone = TimeZone(secondsFromGMT: 0) guard let due = formatter.date(from: (try container.decode(String.self, forKey: CodingKeys.due))) else { throw DecodingError.typeMismatch(Date.self, DecodingError.Context(codingPath: [CodingKeys.due], debugDescription: "String could not be converted to Date")) } self.due = due } } } ``` This workaround now produces proper JSON content: ```json { "options": { "due": "2023-01-13T11:49:59Z", "isEnabled": true } } ``` ### Environment mysql server: 8.0.27 framework: 4.67.4 toolbox: 18.6.0
2 条评论