Skip to content

database update with nil on a Codable type does not change the column to null #838

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

Closed
alexzielenski opened this issue Sep 8, 2018 · 2 comments
Labels

Comments

@alexzielenski
Copy link

alexzielenski commented Sep 8, 2018

Build Information

  • Version: 0.11.5
  • macOS 10.13.6
  • CocoaPods integration

General guidelines

If you run try db.run(table.filter(id == desiredID).update(modelObject)) where modelObject is a Codable struct containing an optional value where the corresponding column is defined as nullable, the SQL generated will not include the set to null as expected.

Example:

struct DBAllocation: Codable {
        let amount: Double
        let note: String
        let strategy: AllocationInterval.Datatype
        let tag_id: Int?
        let start_date: Date.Datatype
        let end_date: Date.Datatype?
}

Executing the update with the above struct where end_date is nil produces the following SQL
UPDATE "allocations" SET "amount" = 60.0, "note" = 'Electric', "strategy" = 'Monthly', "tag_id" = 4, "start_date" = '2018-08-01T07:00:00.000' WHERE ("id" = 5)

which excludes the end_date column set to NULL as I'd expect.

@alexzielenski
Copy link
Author

alexzielenski commented Sep 8, 2018

It seems like in Coding.swift the methods of KeyedEncodingContainerProtocol for encoding optional values were excluded. To be honest, they are kind of non-intuitive. I don't understand why there is a separate encodeNil if it is not going to be used when optional types are indeed nil. Either way, adding the following into that file solved the issue for me:

        ...
        func encodeIfPresent(_ value: Int?, forKey key: MyKey) throws {
            guard let value = value else {
                try encodeNil(forKey: key)
                return
            }
            try encode(value, forKey: key)
        }
        
        func encodeIfPresent(_ value: String?, forKey key: MyKey) throws {
            guard let value = value else {
                try encodeNil(forKey: key)
                return
            }
            try encode(value, forKey: key)
        }
        ...

@jberkel
Copy link
Collaborator

jberkel commented Sep 22, 2018

would you mind submitting a PR with these changes?

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

No branches or pull requests

3 participants