vapor/fluent-mysql-driver

Could not convert MySQL data to Date on time field

eugeniobaglieri opened this issue · 1 comments

Hi, I'm trying to save the time giving a swift date object.
I'm not getting any error on save and the time is saved without errors.
But when I try to query this model I get this error:

invalid field: 'opening_time', type: Date, error: typeMismatch(Foundation.Date, Swift.DecodingError.Context(codingPath: [], debugDescription: "Could not convert MySQL data to Date: <MYSQL_TYPE_TIME>", underlyingError: nil)) [request-id: C9E79175-5642-4AF1-B362-5FFDF0F9F077] (App/ErrorMiddleware.swift:63)

I defined this model:

final class Club: Model {
    
    static var schema: String { "clubs" }
    
    @ID(key: .id)
    var id: UUID?
    
    @Field(key: "name")
    var name: String
    
    @Field(key: "contact")
    var contact: String
    
    @Field(key: "address")
    var address: String
    
    @Field(key: "latitude")
    var latitude: Double
    
    @Field(key: "longitude")
    var longitude: Double
    
    @Children(for: \.$club)
    var playgrounds: [Playground]
    
    @OptionalChild(for: \.$club)
    var user: User?
    
    @Field(key: "active")
    var active: Bool
    
    @Field(key: "opening_time")
    var openingTime: Date
    
    @Field(key: "closing_time")
    var closingTime: Date
    
    @Field(key: "time_slot_duration")
    var timeSlotDuration: Int
    
    @Timestamp(key: "created_at", on: .create)
    var createdAt: Date?
    
    @Timestamp(key: "updated_at", on: .update)
    var updatedAt: Date?
    
    init() {}
}

with this schema:

func prepare(on database: Database) async throws {
        try await database.schema(Club.schema)
            .id()
            .field("name", .string, .required)
            .field("contact", .string, .required)
            .field("address", .string, .required)
            .field("latitude", .double, .required)
            .field("longitude", .double, .required)
            .field("opening_time", .time, .required)
            .field("closing_time", .time, .required)
            .field("time_slot_duration", .int, .required)
            .field("active", .bool, .required, .sql(.default(true)))
            .field("created_at", .datetime, .required)
            .field("updated_at", .datetime)
            .create()
    }

On query i should obtain an object with populated openingTime and closingTime

Environment

  • Framework: 4.78.2
  • Foolbox: main (83d3503)
  • OS version: Ventura 13.5
0xTim commented

Yeah the trouble is there is no good way to represent time in Swift (the same applies to date fields as well). I'm not sure what the best suggested solution to this is, but maybe @gwynne can advise.

Each time this comes up I'm of the mind we should create our own types for only date and only time but there are a lot of edge cases