Add Statement::parameter_name

This commit is contained in:
Nick Hynes 2021-04-25 18:53:37 -05:00 committed by Thom Chiovoloni
parent 9ea5e2fc04
commit b8b1138fcf
2 changed files with 47 additions and 0 deletions

View File

@ -144,6 +144,18 @@ impl RawStatement {
}) })
} }
#[inline]
pub fn bind_parameter_name(&self, index: i32) -> Option<&CStr> {
unsafe {
let name = ffi::sqlite3_bind_parameter_name(self.ptr, index);
if name.is_null() {
None
} else {
Some(CStr::from_ptr(name))
}
}
}
#[inline] #[inline]
pub fn clear_bindings(&self) -> c_int { pub fn clear_bindings(&self) -> c_int {
unsafe { ffi::sqlite3_clear_bindings(self.ptr) } unsafe { ffi::sqlite3_clear_bindings(self.ptr) }

View File

@ -521,6 +521,30 @@ impl Statement<'_> {
Ok(self.stmt.bind_parameter_index(name)) Ok(self.stmt.bind_parameter_index(name))
} }
/// Return the SQL parameter name given its (one-based) index (the inverse of
/// [`Statement::parameter_index`]).
///
/// ```rust,no_run
/// # use rusqlite::{Connection, Result};
/// fn example(conn: &Connection) -> Result<()> {
/// let stmt = conn.prepare("SELECT * FROM test WHERE name = :example")?;
/// let index = stmt.parameter_name(1);
/// assert_eq!(index, Some(":example"));
/// Ok(())
/// }
/// ```
///
/// # Failure
///
/// Will return `None` if the column index is out of bounds or if the parameter
/// is positional.
#[inline]
pub fn parameter_name(&self, index: usize) -> Option<&'_ str> {
self.stmt.bind_parameter_name(index as i32).map(|name| {
str::from_utf8(name.to_bytes()).expect("Invalid UTF-8 sequence in parameter name")
})
}
#[inline] #[inline]
pub(crate) fn bind_parameters<P>(&mut self, params: P) -> Result<()> pub(crate) fn bind_parameters<P>(&mut self, params: P) -> Result<()>
where where
@ -1334,6 +1358,17 @@ mod test {
Ok(()) Ok(())
} }
#[test]
fn test_parameter_name() -> Result<()> {
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE test (name TEXT, value INTEGER)")?;
let stmt = db.prepare("INSERT INTO test (name, value) VALUES (:name, ?3)")?;
assert_eq!(stmt.parameter_name(0), None);
assert_eq!(stmt.parameter_name(1), Some(":name"));
assert_eq!(stmt.parameter_name(2), None);
Ok(())
}
#[test] #[test]
fn test_empty_stmt() -> Result<()> { fn test_empty_stmt() -> Result<()> {
let conn = Connection::open_in_memory()?; let conn = Connection::open_in_memory()?;