groue / GRDB.swift

A toolkit for SQLite databases, with a focus on application development

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 {

Screenshot 2023-12-11 at 4 36 29 PM

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.