GRDB called a `Not implemented` function while inserting.
DandyLyons opened this issue · comments
What did you do?
Still learning GRDB and SQLite. This issue could very well be due to me using GRDB wrong, but I thought I'd mention it because I got a Not implemented
error.
I have a LiveEvent
table with a one to many relationship to Platform
.
struct Migration20231121: DBMigration {
static func migrate(_ db: Database) throws {
try db.create(table: "platform") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text).notNull()
}
try db.create(table: "liveEvent") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text)
.notNull().defaults(to: "")
t.column("kind", .jsonText).notNull().defaults(to: "[]") // [LiveEvent.Kind]
t.column("platformId", .integer)
.notNull()
.references("platform", onDelete: .restrict, onUpdate: .cascade)
t.column("status", .text).notNull()
t.column("url", .text) // Use .text for plain URL
t.column("start", .datetime).notNull()
t.column("end", .datetime)
}
}
}
I'm having trouble figuring out how to insert a LiveEvent when it must have a platformId.
If I try this, it says I can't have a transaction within a transaction:
try db.inTransaction {
let persistedPlatform = try platform.upsertAndFetch(db, as: PersistedPlatform.self)
var liveEventToPersist = newLiveEvent
liveEventToPersist.platformId = persistedPlatform.id
try liveEventToPersist.insert(db)
return .commit
}
If I try to run it in a inSavepoint
then I crash with this error:
- try db.inTransaction {
+ try db.inSavePoint {
What did you expect to happen?
I expected to insert the models into my database.
Environment
FYI, I am using an approach very similar to what was discussed here, using Persisted
.
Also, I'm using TCA and swift-dependencies.
GRDB flavor(s): (GRDB, SQLCipher, Custom SQLite build?)
GRDB version: 6.21.0
Installation method: SPM
Xcode version: 15.0.1
Swift version: 5.9
Platform(s) running GRDB: iOS
macOS version running Xcode: 14.1
Hello @DandyLyons,
The GRDB support for nested Codable containers is, as the error message says, not implemented. It is missing, if you prefer.
If you don't know what nested containers are, you're not alone. They are an infrequently used feature of the Codable runtime. This forum thread brings some light.
Nested containers are so infrequently used that this issue is the first report since GRDB support for Codable has shipped, five years ago.
As a conclusion, you have to ways to avoid this fatal error: have your Codable type avoid calling nestedContainer(keyedBy:forKey:)
(I suppose it is explicitly called somewhere in your app), or submit a pull request to the GRDB repository that brings support for nested containers and removes the "Not implemented" fatal error.
Thank you. That's very interesting. I never explicitly called it. It must be called by some Library I depend on.
Thank you very much for your help.