I'm trying to use SQLite.swift's Codable
functionality to insert a row, but am getting the following error message:
Swift.EncodingError.Context(codingPath: [], debugDescription: "Top-level
MyEnum encoded as number JSON fragment.", underlyingError: nil))
My enum extends Int
and Codable
:
enum MyEnum : Int, Codable {
case FIRSTVAL = 0, SECONDVAL = 1
}
And the class consuming it looks like this:
class MyClass : Codable {
static let tableRef = Table("MyTable")
static let idColumn = Expression<Int>("MyTableId");
static let nameColumn = Expression<String>("Name")
static let myEnumValColumn = Expression<Int>("MyEnumVal")
static func createTable(_ db : Connection) throws {
try db.run(tableRef.create(ifNotExists: true) { t in
t.column(idColumn, primaryKey: true)
t.column(nameColumn)
t.column(myEnumValColumn)
})
}
var MyTableId : Int!
var Name : String
var MyEnumVal : MyEnum
}
The code that attempts to insert the row and causes the error to be thrown:
try db.run(MyClass.tableRef.insert(anInstanceOfMyClass))
I know in the documentation for SQLite.swift it says:
The encodable and decodable objects can only use the following types:
- Int, Bool, Float, Double, String
- Nested Codable types that will be encoded as JSON to a single column
Is there a way to force it to use the rawValue
of the enum (as it extends Int
anyway), perhaps by implementing the encode/decode method manually for either MyEnum
or MyClass
? I'm trying to avoid having to manually write code to deserialise the row from the database back into an object and serialise from an object ready for the database. For example I previously had the following methods in MyClass
(as well as other bits of code that loaded entities from the DB too and had to deserialise them):
init(row : Row) {
self.MyTableId = row[MyClass.idColumn]
self.Name = row[MyClass.nameColumn]
self.MyEnumVal = MyEnum(rawValue: Int(row[MyClass.myEnumValColumn]))!
}
func insert(_ db : Connection) throws {
let insert = MyClass.tableRef.insert(
MyClass.idColumn <- Int(MyTableId),
MyClass.nameColumn <- Name,
MyClass.myEnumValColumn <- Int(MyEnumVal.rawValue)
)
try db.run(insert)
}