Your code won't exit while loop because the sqlite3_prepare_v2 will not fail. But no while loop is needed. You can do something like:
func insertDiveGear() {
var statement: OpaquePointer? = nil
let names = itemDataArray
let update = "INSERT INTO DiveGearForDive (id, name) VALUES (?, ?);"
for (diveNumber, name) in names.enumerated() {
if sqlite3_prepare_v2(dlDatabase.database, update, -1, &statement, nil) == SQLITE_OK {
sqlite3_bind_int(statement, 1, Int32(diveNumber))
sqlite3_bind_text(statement, 2, name, -1, SQLITE_TRANSIENT)
if sqlite3_step(statement) == SQLITE_DONE {
print("Successfully inserted row.")
} else {
print("Could not insert row.")
}
sqlite3_finalize(statement)
}
}
}
Or, even more efficient, prepare the statement only once, and then loop through binding, stepping, and then resetting:
func insertDiveGear() {
var statement: OpaquePointer? = nil
let names = itemDataArray
let update = "INSERT INTO DiveGearForDive (id, name) VALUES (?, ?);"
guard sqlite3_prepare_v2(dlDatabase.database, update, -1, &statement, nil) == SQLITE_OK else {
let errmsg = String(cString: sqlite3_errmsg(dlDatabase.database))
print("failure preparing: \(errmsg)")
return
}
for (diveNumber, name) in names.enumerated() {
sqlite3_bind_int(statement, 1, Int32(diveNumber))
sqlite3_bind_text(statement, 2, name, -1, SQLITE_TRANSIENT)
if sqlite3_step(statement) == SQLITE_DONE {
print("Successfully inserted row.")
} else {
print("Could not insert row.")
}
sqlite3_reset(statement)
}
sqlite3_finalize(statement)
}
I didn't know what to make of that let diveNumber = Int32(diveNumber) line (where is diveNumber defined; using the same name?; etc.), so adjust that as you see fit, but the main question is why the loop didn't exit, and it's because sqlite3_prepare_v2 will always return SQLITE_OK if the SQL is well formed.
Also note, I used SQLITE_TRANSIENT constant (see Cannot invoke initializer for type 'sqlite3_destructor_type') in conjunction with sqlite3_bind_text to ensure that SQLite creates its own copy of the string that it received, which is prudent when dealing with Swift strings.
sqlite3_prepare_v2should be called once, andsqlite3_bind_XXX/sqlite3_stepin a loop for all items to insert.sqlite3_reseteach time, too.