As part of a migration effort, I am creating a SQLite DB for the first time.
Based on the example documentation from the site
I am creating an Insert statement and then running it to insert the record.
I get the following error on each line that has an Int64 value:
Cannot convert value of type 'Expression<Int64>' to expected argument type 'Expression<Int?>'
I have no optional values in my code, it is being introduced in these lines.
I don't understand why, or what I should do to make the compiler happy.
import SQLite
extension Connection {
/// Source could be a json file or a migration from Realm, for example
static func insertAprilRecords(records: [AprilRecord]) {
/// List target db's fields
let id = Expression<Int64>(AprilRecord.Key.id.rawValue)
let activity = Expression<Int64>(AprilRecord.Key.activity.rawValue)
let timestamp = Expression<Double>(AprilRecord.Key.timestamp.rawValue)
let details = Expression<String>(AprilRecord.Key.details.rawValue)
let isCompleted = Expression<Bool>(AprilRecord.Key.isCompleted.rawValue)
let table = Table("record") // equivalent of `Goal`
do {
let db = try Connection(DBSetup.dbURL.path)
try db.transaction {
for record in records {
let insertionRecord = table.insert(
// error: Cannot convert value of type 'Expression<Int64>' to expected argument
activity <- record.activity,
timestamp <- record.timestamp,
details <- record.details,
isCompleted <- record.isCompleted,
)
let rowid = try db.run(insertionRecord)
}
}
} catch {
print("failed to add records to the DB")
print(error)
print(error.localizedDescription)
}
}
}
I don't have any optional fields:
public struct AprilRecord: Identifiable, Codable {
public var id: Int
var activity: Int
var timestamp: Double
var details: String
var isCompleted: Bool
}
for completeness (so it will compile), here are my keys:
extension AprilRecord {
enum Key: String, CaseIterable {
case id, activity, timestamp, details, isCompleted
}
}
Since I can't find any examples of this problem online I expect I'm doing something fundamentally wrong.
What is the correct way to insert non-optional Int64 values?
Edit:
If I modify the Expression definition to use an optional:
let category = Expression<Int64?>(AprilRecord.Key.category.rawValue)
I get an error message I don't expect for the line:
category <- record.category,
Binary operator '<-' cannot be applied to operands of type 'Expression<Int64?>' and 'Int'
Shouldn't the left hand side be Expression<Int64?> at that point? Certainly not an Int.
CodePudding user response:
OK, I was doing something fundamentally wrong.
Although the documentation shows copious use of Expression<Int64>, I should be using Expression<Int>. As in:
let activity = Expression<Int>(AprilRecord.Key.activity.rawValue)
from the documentation (same link as above):
*While Int64 is the basic, raw type (to preserve 64-bit integers on 32-bit platforms), Int and Bool work transparently.
It really does work transparently!
Thanks to Joakim and Ptit for responding.