mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-26 11:31:37 +08:00
Make parameter_index return a Result<Option<_>> instead of squashing
string conversion errors into None.
This commit is contained in:
parent
186cb5893b
commit
b7468b2c4b
@ -1,9 +1,9 @@
|
|||||||
use std::ffi::CString;
|
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
|
|
||||||
use {SqliteResult, SqliteError, SqliteConnection, SqliteStatement, SqliteRows, SqliteRow};
|
use {SqliteResult, SqliteError, SqliteConnection, SqliteStatement, SqliteRows, SqliteRow,
|
||||||
|
str_to_cstring};
|
||||||
use types::ToSql;
|
use types::ToSql;
|
||||||
|
|
||||||
impl SqliteConnection {
|
impl SqliteConnection {
|
||||||
@ -65,17 +65,15 @@ impl<'conn> SqliteStatement<'conn> {
|
|||||||
///
|
///
|
||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Return None if `name` is invalid or if no matching parameter is found.
|
/// Will return Err if `name` is invalid. Will return Ok(None) if the name
|
||||||
pub fn parameter_index(&self, name: &str) -> Option<i32> {
|
/// is valid but not a bound parameter of this statement.
|
||||||
unsafe {
|
pub fn parameter_index(&self, name: &str) -> SqliteResult<Option<i32>> {
|
||||||
CString::new(name).ok().and_then(|c_name| {
|
let c_name = try!(str_to_cstring(name));
|
||||||
match ffi::sqlite3_bind_parameter_index(self.stmt, c_name.as_ptr()) {
|
let c_index = unsafe { ffi::sqlite3_bind_parameter_index(self.stmt, c_name.as_ptr()) };
|
||||||
0 => None, // A zero is returned if no matching parameter is found.
|
Ok(match c_index {
|
||||||
n => Some(n),
|
0 => None, // A zero is returned if no matching parameter is found.
|
||||||
}
|
n => Some(n),
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute the prepared statement with named parameter(s).
|
/// Execute the prepared statement with named parameter(s).
|
||||||
@ -98,8 +96,8 @@ impl<'conn> SqliteStatement<'conn> {
|
|||||||
/// Will return `Err` if binding parameters fails, the executed statement returns rows (in
|
/// Will return `Err` if binding parameters fails, the executed statement returns rows (in
|
||||||
/// which case `query` should be used instead), or the underling SQLite call fails.
|
/// which case `query` should be used instead), or the underling SQLite call fails.
|
||||||
pub fn execute_named(&mut self, params: &[(&str, &ToSql)]) -> SqliteResult<c_int> {
|
pub fn execute_named(&mut self, params: &[(&str, &ToSql)]) -> SqliteResult<c_int> {
|
||||||
|
try!(self.bind_named_parameters(params));
|
||||||
unsafe {
|
unsafe {
|
||||||
try!(self.bind_named_parameters(params));
|
|
||||||
self.execute_()
|
self.execute_()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,20 +126,17 @@ impl<'conn> SqliteStatement<'conn> {
|
|||||||
params: &[(&str, &ToSql)])
|
params: &[(&str, &ToSql)])
|
||||||
-> SqliteResult<SqliteRows<'a>> {
|
-> SqliteResult<SqliteRows<'a>> {
|
||||||
self.reset_if_needed();
|
self.reset_if_needed();
|
||||||
|
try!(self.bind_named_parameters(params));
|
||||||
unsafe {
|
|
||||||
try!(self.bind_named_parameters(params));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.needs_reset = true;
|
self.needs_reset = true;
|
||||||
Ok(SqliteRows::new(self))
|
Ok(SqliteRows::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn bind_named_parameters(&mut self, params: &[(&str, &ToSql)]) -> SqliteResult<()> {
|
fn bind_named_parameters(&mut self, params: &[(&str, &ToSql)]) -> SqliteResult<()> {
|
||||||
// Always check that the number of parameters is correct.
|
// Always check that the number of parameters is correct.
|
||||||
assert!(params.len() as c_int == ffi::sqlite3_bind_parameter_count(self.stmt),
|
assert!(params.len() as c_int == unsafe { ffi::sqlite3_bind_parameter_count(self.stmt) },
|
||||||
"incorrect number of parameters to query(): expected {}, got {}",
|
"incorrect number of parameters to query(): expected {}, got {}",
|
||||||
ffi::sqlite3_bind_parameter_count(self.stmt),
|
unsafe { ffi::sqlite3_bind_parameter_count(self.stmt) },
|
||||||
params.len());
|
params.len());
|
||||||
|
|
||||||
// In debug, also sanity check that we got distinct parameter names.
|
// In debug, also sanity check that we got distinct parameter names.
|
||||||
@ -158,11 +153,14 @@ impl<'conn> SqliteStatement<'conn> {
|
|||||||
"named parameters must be unique");
|
"named parameters must be unique");
|
||||||
|
|
||||||
for &(name, value) in params {
|
for &(name, value) in params {
|
||||||
let i = try!(self.parameter_index(name).ok_or(SqliteError {
|
if let Some(i) = try!(self.parameter_index(name)) {
|
||||||
code: ffi::SQLITE_MISUSE,
|
try!(self.conn.decode_result(unsafe { value.bind_parameter(self.stmt, i) }));
|
||||||
message: format!("Invalid parameter name: {}", name),
|
} else {
|
||||||
}));
|
return Err(SqliteError {
|
||||||
try!(self.conn.decode_result(value.bind_parameter(self.stmt, i)));
|
code: ffi::SQLITE_MISUSE,
|
||||||
|
message: format!("Invalid parameter name: {}", name),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user