-
Is there a way to make this work? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hello @hell001, It is not possible to write You want to fetch values of multiple types, so we have no choice: we have to look for another fetching technique. protocol MyProtocol { ... }
struct A: MyProtocol { ... }
struct B: MyProtocol { ... }
// How to fetch an array that contains some A and some B?
let myRecords: [MyProtocol] = ... Some database rows encode an Since there is no concrete type that is both an Please find below a complete sample code that you will adapt for you own use case: import GRDB
// MARK: Protocol & Concrete Types
protocol MyProtocol { }
struct A: MyProtocol, FetchableRecord, Decodable { }
struct B: MyProtocol, FetchableRecord, Decodable { }
// MARK: Database setup
let dbQueue = DatabaseQueue()
try dbQueue.write { db in
try db.create(table: "myRecord") { t in
t.autoIncrementedPrimaryKey("id")
t.column("kind", .text).notNull()
}
try db.execute(sql: """
INSERT INTO myRecord (kind) VALUES ('A');
INSERT INTO myRecord (kind) VALUES ('B');
INSERT INTO myRecord (kind) VALUES ('A');
INSERT INTO myRecord (kind) VALUES ('LOL');
""")
}
// MARK: Fetch records of various types
try dbQueue.read { db in
// A request for all rows in this table
let request = Table("myRecord").all()
// A cursor for all rows fetched by the request
let rowCursor = try request.fetchCursor(db)
// Turns rows into records, skipping rows with unknown kind
let myRecordCursor = rowCursor.compactMap { row -> MyProtocol? in
switch row["kind"] as String {
case "A":
return A(row: row)
case "B":
return B(row: row)
default:
// unknown kind: ignore this row
return nil
}
}
// Build the [MyProtocol] array
let myRecords = try Array(myRecordCursor)
print(myRecords) // [A, B, A]
} |
Beta Was this translation helpful? Give feedback.
Hello @hell001,
It is not possible to write
MyProtocol.fetchAll(db)
, as the compiler says. You have to tell which concrete type (struct, class or enum) should be decoded. And you'll fetch an homogeneous array, that only contains values of this type.You want to fetch values of multiple types, so we have no choice: we have to look for another fetching technique.
Some database rows encode an
A
, and some other encode aB
. Let's suppose the type of each encoded value is stored in a columnkind
whose value is"A"
, or"B"