vapor / mysql-nio

🐬 Non-blocking, event-driven Swift client for MySQL.
MIT License
91 stars 26 forks source link

Extended Integer Support #62

Open masterofinsanity opened 3 years ago

masterofinsanity commented 3 years ago

Is your feature request related to a problem? Please describe. I've noticed that inserting an UInt64 with a value bigger than Int.max into a field using FluentMySQL does not work. This is because FluentMySQL only makes use of the MySQLData init(int:) initializer. (FluentMySQL also translates UInt64 to INT in sql but this is another issue).

Describe the solution you'd like As PostgresNIO also includes separate initializers and conversion methods for the different integer types i would suggest to also implement these in mysql-nio.

Custom initializers for MySQLData:

struct MySQLData {
//...

    //Private generic initializers
    private init<T>(type: MySQLProtocol.DataType, value: T, isUnsigned: Bool) where T: FixedWidthInteger {
        self.format = .binary
        self.type = type
        self.buffer = .init(integer: value, endianness: .little)
        self.isUnsigned = isUnsigned
    }
    private init<T>(type: MySQLProtocol.DataType, value: T) where T: FixedWidthInteger, T: SignedInteger {
        self.init(type: type, value: value, isUnsigned: false)
    }
    private init<T>(type: MySQLProtocol.DataType, value: T) where T: FixedWidthInteger, T: UnsignedInteger {
        self.init(type: type, value: value, isUnsigned: true)
    }

    //public initializers with specified MySQL DataType
    public init(int8 int: Int8) {
        self.init(type: .tiny, value: int)
    }

    public init(uint64 int: UInt64) {
        self.init(type: .longlong, value: int)
    }
    //...
}

Separate MySQLDataConvertible-Conformance -> Instead of one extension for FixedWidthInteger. NumericCast is no longer necessary.

extension UInt64: MySQLDataConvertible {
    public init?(mysqlData: MySQLData) {
        guard let int = mysqlData.uint64 else {
            return nil
        }
        self = int
    }

    public var mysqlData: MySQLData? {
        return .init(uint64: self)
    }
}