我尝试使用SQLite.swift的Codable
functionality插入一行,但收到以下错误消息:
Swift.EncodingError.Context(codingPath: [], debugDescription: "Top-level
MyEnum encoded as number JSON fragment.", underlyingError: nil))
我的枚举扩展了Int
和Codable
:
enum MyEnum : Int, Codable {
case FIRSTVAL = 0, SECONDVAL = 1
}
使用它的类看起来像这样:
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
}
尝试插入行并导致抛出错误的代码:
try db.run(MyClass.tableRef.insert(anInstanceOfMyClass))
我在SQLite.swift的文档中知道它说:
可编码和可解码对象只能使用以下类型:
- Int,Bool,Float,Double,String
- 嵌套的Codable类型,将被编码为单个列的JSON
是否有办法强制它使用枚举的rawValue
(因为它无论如何都扩展Int
),也许是通过为MyEnum
手动实现编码/解码方法或MyClass
?我试图避免手动编写代码以将数据库中的行反序列化为对象,并从准备好数据库的对象中进行序列化。例如,我以前在MyClass
中有以下方法(以及从DB加载实体的其他代码,并且必须对它们进行反序列化):
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)
}