///|
struct Connection(Ref[@ffi.Sqlite3?])
///|
fn Connection::handle(self : Connection) -> @ffi.Sqlite3 raise SqliteError {
match self.0.val {
Some(db) => db
None => raise sqlite_misuse("sqlite3: connection is closed")
}
}
///|
fn Connection::error(self : Connection, raw_code : Int) -> SqliteError {
match self.0.val {
Some(db) => sqlite_error(raw_code, @ffi.sqlite3_errmsg(db))
None => sqlite_error(raw_code, "sqlite3: database connection is closed")
}
}
///|
const SQLITE_OPEN_READWRITE : Int = 0x00000002
///|
const SQLITE_OPEN_CREATE : Int = 0x00000004
///|
pub fn Connection::open(filename : String) -> Connection raise SqliteError {
if filename.contains_code_unit(0x0000) {
raise sqlite_misuse("sqlite3: filename contains a NUL code unit")
}
let filename = @utf8.encode(filename)
let flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
let rescode = Ref(SQLITE_OK)
let db = @ffi.sqlite3_open_v2(filename, flags, rescode)
if rescode.val == SQLITE_OK {
return Connection(Ref(Some(db)))
} else {
let error = if @ffi.sqlite3_is_null(db) {
sqlite_error(rescode.val, "sqlite3: failed to allocate a database handle")
} else {
sqlite_error(rescode.val, @ffi.sqlite3_errmsg(db))
}
let _ = @ffi.sqlite3_close(db)
raise error
}
}
///|
pub fn Connection::close(self : Connection) -> Unit raise SqliteError {
match self.0.val {
None => ()
Some(db) => {
let rescode = @ffi.sqlite3_close(db)
if rescode == SQLITE_OK {
self.0.val = None
} else {
raise self.error(rescode)
}
}
}
}