sqlite3: Implement sqlite3_bind_parameter_index()

This commit is contained in:
Pekka Enberg
2025-08-24 20:10:31 +03:00
parent 4fc7b94a6b
commit c428ff06b2
4 changed files with 67 additions and 0 deletions

View File

@@ -2166,6 +2166,10 @@ impl Statement {
self.program.parameters.count()
}
pub fn parameter_index(&self, name: &str) -> Option<NonZero<usize>> {
self.program.parameters.index(name)
}
pub fn bind_at(&mut self, index: NonZero<usize>, value: Value) {
self.state.bind_at(index, value);
}

View File

@@ -153,6 +153,8 @@ int sqlite3_bind_parameter_count(sqlite3_stmt *_stmt);
const char *sqlite3_bind_parameter_name(sqlite3_stmt *_stmt, int _idx);
int sqlite3_bind_parameter_index(sqlite3_stmt *_stmt, const char *_name);
int sqlite3_bind_null(sqlite3_stmt *_stmt, int _idx);
int sqlite3_bind_int64(sqlite3_stmt *_stmt, int _idx, int64_t _val);

View File

@@ -538,6 +538,28 @@ pub unsafe extern "C" fn sqlite3_bind_parameter_name(
}
}
#[no_mangle]
pub unsafe extern "C" fn sqlite3_bind_parameter_index(
stmt: *mut sqlite3_stmt,
name: *const ffi::c_char,
) -> ffi::c_int {
if stmt.is_null() || name.is_null() {
return 0;
}
let stmt = &*stmt;
let name_str = match CStr::from_ptr(name).to_str() {
Ok(s) => s,
Err(_) => return 0,
};
if let Some(index) = stmt.stmt.parameter_index(name_str) {
index.get() as ffi::c_int
} else {
0
}
}
#[no_mangle]
pub unsafe extern "C" fn sqlite3_bind_null(stmt: *mut sqlite3_stmt, idx: ffi::c_int) -> ffi::c_int {
if stmt.is_null() {

View File

@@ -50,6 +50,7 @@ extern "C" {
fn sqlite3_bind_int(stmt: *mut sqlite3_stmt, idx: i32, val: i64) -> i32;
fn sqlite3_bind_parameter_count(stmt: *mut sqlite3_stmt) -> i32;
fn sqlite3_bind_parameter_name(stmt: *mut sqlite3_stmt, idx: i32) -> *const libc::c_char;
fn sqlite3_bind_parameter_index(stmt: *mut sqlite3_stmt, name: *const libc::c_char) -> i32;
fn sqlite3_clear_bindings(stmt: *mut sqlite3_stmt) -> i32;
fn sqlite3_column_name(stmt: *mut sqlite3_stmt, idx: i32) -> *const libc::c_char;
fn sqlite3_last_insert_rowid(db: *mut sqlite3) -> i32;
@@ -1240,4 +1241,42 @@ mod tests {
assert_eq!(sqlite3_close(db), SQLITE_OK);
}
}
#[test]
fn test_sqlite3_bind_parameter_index() {
const SQLITE_OK: i32 = 0;
unsafe {
let mut db: *mut sqlite3 = ptr::null_mut();
let mut stmt: *mut sqlite3_stmt = ptr::null_mut();
assert_eq!(sqlite3_open(c":memory:".as_ptr(), &mut db), SQLITE_OK);
assert_eq!(
sqlite3_prepare_v2(
db,
c"SELECT * FROM sqlite_master WHERE name = :table_name AND type = :object_type"
.as_ptr(),
-1,
&mut stmt,
ptr::null_mut()
),
SQLITE_OK
);
let index1 = sqlite3_bind_parameter_index(stmt, c":table_name".as_ptr());
assert_eq!(index1, 1);
let index2 = sqlite3_bind_parameter_index(stmt, c":object_type".as_ptr());
assert_eq!(index2, 2);
let index3 = sqlite3_bind_parameter_index(stmt, c":nonexistent".as_ptr());
assert_eq!(index3, 0);
let index4 = sqlite3_bind_parameter_index(stmt, ptr::null());
assert_eq!(index4, 0);
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
}
}
}