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

SQLiteDecoder & Codable with NULL Values #997

Closed
Sevyls opened this issue Apr 24, 2020 · 8 comments · Fixed by #1224
Closed

SQLiteDecoder & Codable with NULL Values #997

Sevyls opened this issue Apr 24, 2020 · 8 comments · Fixed by #1224

Comments

@Sevyls
Copy link

Sevyls commented Apr 24, 2020

Are null values actually supported by your SQLiteDecoder?

Build Information

CocoaPods, SQLite.swift version 0.12.2
iOS 13.4, XCode 11.4.1

General guidelines

I just tried to read an array of my table's contents, but then I got an exception.

In Coding.swift:235 I get an error by QueryError.unexpectedNullValue.

Are null values within Codables supported?

@TenMaKo
Copy link

TenMaKo commented Apr 27, 2020

No. You need to handle it yourself.

I came up with this if you wanna try :

Put this somewhere

protocol SQLiteCompatibleType: Encodable {}
extension Int: SQLiteCompatibleType {}
extension String: SQLiteCompatibleType {}
extension Bool: SQLiteCompatibleType {}
extension Double: SQLiteCompatibleType {}
extension Float: SQLiteCompatibleType {}
extension Data: SQLiteCompatibleType {}

extension KeyedEncodingContainerProtocol {
    mutating func encodeNullable<T>(_ value: T?, forKey key: Key) throws where T: SQLiteCompatibleType {
        if let unwrappedValue = value {
            if let int = unwrappedValue as? Int {
                try self.encode(int, forKey: key)
            } else if let double = unwrappedValue as? Double {
                try self.encode(double, forKey: key)
            } else if let float = unwrappedValue as? Float {
                try self.encode(float, forKey: key)
            } else if let bool = unwrappedValue as? Bool {
                try self.encode(bool, forKey: key)
            } else if let data = unwrappedValue as? Data {
                try self.encode(data, forKey: key)
            } else if let string = unwrappedValue as? String {
                try self.encode(string, forKey: key)
            } else {
                try self.encode(unwrappedValue, forKey: key)
            }
        } else {
            try self.encodeNil(forKey: key)
        }
    }
}

and change the following func in Coding.swift :

func encode<T>(_ value: T, forKey key: Key) throws where T: Swift.Encodable {
            if let data = value as? Data {
                self.encoder.setters.append(Expression(key.stringValue) <- data)
            } else if let string = value as? String {
                self.encoder.setters.append(Expression(key.stringValue) <- string)
            } else {
                let encoded = try JSONEncoder().encode(value)
                let string = String(data: encoded, encoding: .utf8)
                self.encoder.setters.append(Expression(key.stringValue) <- string)
            }
}

And then in func encode(to encoder: Encoder) throws in your object class definition, use encodeNullable and in required convenience init(from decoder: Decoder) throws use decodeIfPresent for optional values

Hope it will help :)

@Sevyls
Copy link
Author

Sevyls commented Apr 27, 2020

Thanks for your support, will try that.

@rahulvyas
Copy link

rahulvyas commented Apr 28, 2020

@TenMaKo
I have added SQLIte.swift using SPM (Swift Package Manager). How do I update Coding.swift file code ?

@TenMaKo
Copy link

TenMaKo commented Apr 29, 2020

@TenMaKo
I have added SQLIte.swift using SPM (Swift Package Manager). How do I update Coding.swift file code ?

I don’t use SPM so I’m not sure about this but I think you can’t cause SPM import pre-built packages.
Maybe you will need to fork this repo, modify the file and then import the lib from your own repo :/
Again, it’s just a guess.

@rahulvyas
Copy link

@TenMaKo Don't you think you should create a PR and then merge this fix into master. More people are facing the issue..

@TenMaKo
Copy link

TenMaKo commented Apr 29, 2020

@TenMaKo Don't you think you should create a PR and then merge this fix into master. More people are facing the issue..

No sorry cause this is just a workaround. A clean fix should make standard Codable usage for this lib handle optionals correctly.

@rahulvyas
Copy link

@TenMaKo got it thanks for clarification...

@nathanfallet
Copy link
Collaborator

@TenMaKo Feel free to open a PR to fix this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants