I've following sqlite code using C api within Swift having a read and a delete operation for review.
For those not familiar with Swift, defer
will execute after the end of the function.
Since I'm not closing the database connection and keeping it alive, I'm calling sqlite3_db_cacheflush(database)
to flush out the changes to the disk. Link
class Database {
internal var database: OpaquePointer! = nil
init(_ database: OpaquePointer) {
self.database = database
}
func deleteById(_ id: Int64) throws -> Int32? {
let sql = "DELETE FROM user WHERE id = \(id)"
defer {
sqlite3_db_cacheflush(database)
}
guard sqlite3_exec(database, sql, nil, nil, nil) == SQLITE_OK else {
throw NSError(domain: String(cString: sqlite3_errmsg(database)), code: 1, userInfo: nil)
}
return sqlite3_changes(database)
}
func findAllDepartments() throws -> [Department]? {
var statement: OpaquePointer? = nil
let sql = "SELECT id, name FROM department"
guard sqlite3_prepare_v2(database, sql, -1, &statement, nil) == SQLITE_OK else {
throw NSError(domain: String(cString: sqlite3_errmsg(database)), code: 1, userInfo: nil)
}
defer {
sqlite3_finalize(statement)
sqlite3_db_cacheflush(database)
}
var departments: [Department] = []
while sqlite3_step(statement) == SQLITE_ROW {
departments.append(Department(id: sqlite3_column_int64(statement, 0), name: String(cString: sqlite3_column_text(statement, 1))))
}
return departments
}
}
Usage of Database Class
do {
if sqlite3_open_v2(url.path, &database, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, nil) == SQLITE_OK { // Existing database (Serialized mode)
let db = Database(database)
try! db.findAllDepartments()
try! db.deleteById(4)
} else { // Error opening database
print(String(cString: sqlite3_errmsg(database)))
}
catch { let error as NSError {
print(error.description)
}