GRDB.swift: GRDB Does not honor the Swift 4 Decodable CodingKey
What did you do?
I mapped the incoming JSON key from uuid to categoryUuid using an enum CodingKeys
public struct Book: Codable {
var userId: Int64?
public var categoryUuid: String
public var title: String
public var languageId: String
public var localizedTitle: String
enum CodingKeys: String, CodingKey {
case userId
case categoryUuid = "uuid"
case title
case languageId
case localizedTitle
}
}
I created an SQLite table with the key categoryUuid
do {
try db.create(table: "book") { bookTable in
print("created: \(bookTable)")
bookTable.column("categoryUuid", .text).primaryKey()
bookTable.column("title", .text)
bookTable.column("languageId", .text)
bookTable.column("localizedTitle", .text)
bookTable.column("userId", .integer).references("user", onDelete: .cascade)
}
}
catch {
print("error making book table: \(error)")
}
I extended the Book struct to contain an enum Columns
extension Book {
enum Columns {
static let userId = Column("userId")
static let categoryUuid = Column("categoryUuid")
static let title = Column("title")
static let languageId = Column("languageId")
static let localizedTitle = Column("localizedTitle")
}
}
I adopted RowConvertible:
extension Book: RowConvertible { }
I override didInsert:
extension Book: MutablePersistable {
public static let databaseTableName = "book"
public mutating func didInsert(with rowID: String, for column: String?) {
categoryUuid = rowID
}
}
Using a Moya Target, I mapped the incoming JSON to a BookResponse(which contains a Book array)
return self.kjvrvgNetworking.rx.request(.books(languageId: L10n.shared.language))
.map { response -> BookResponse in try! response.map(BookResponse.self) }
.flatMap { bookResponse -> Single<[Book]> in Single.just(bookResponse.result)
.flatMap { [unowned self] in self.replacePersistedBooks($0) }
Upon insertion(replacePersistedBooks()), I get the SQLite error:
2018-02-05 09:20:28.662544-0500 All Scripture[47115:782639] [logging] table book has no column named uuid
SQLite error 1 with statement `INSERT INTO "book" ("title", "userId", "uuid", "languageId", "localizedTitle") VALUES (?,?,?,?,?)`: table book has no column named uuid
Check user products failed with error: SQLite error 1 with statement `INSERT INTO "book" ("title", "userId", "uuid", "languageId", "localizedTitle") VALUES (?,?,?,?,?)`: table book has no column named uuid
What did you expect to happen?
I expected GRDB to insert a row using a value named categoryUuid and NOT uuid
What happened instead?
GRDB inserted a row using a value named uuid and NOT categoryUuid
Environment
**GRDB flavor(s):GRDB.swift, RxGRDB **GRDB version: see below
Using GRDB.swift (2.4.1)
Using RxGRDB (0.7.0)
**Installation method: CocoaPods **Xcode version:9.2 **Swift version:4 **Platform(s) running GRDB:iOS **macOS version running Xcode: High Sierra
Demo Project
Please link to or upload a project we can download that reproduces the issue.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 15 (5 by maintainers)
Apologies for my late reply @groue Thank you for clarifying that for me, was exactly what I needed 😄
Hello @Cooparr,
Yes, only custom implementations of
Decodable/Encodablerequirements can deal with distinct coding keys for JSON and the database (or any other coding source/destination). See The userInfo Dictionary for more information.Alternatively, you can just not rely on
Codablefor the database.This is abundantly documented:
For example: