Merge 'sqlite3: Implement sqlite3_get_autocommit()' from Pekka Enberg

Closes #2758
This commit is contained in:
Pekka Enberg
2025-08-24 16:53:04 +03:00
committed by GitHub
2 changed files with 91 additions and 2 deletions

View File

@@ -378,8 +378,17 @@ pub unsafe extern "C" fn sqlite3_deserialize(
}
#[no_mangle]
pub unsafe extern "C" fn sqlite3_get_autocommit(_db: *mut sqlite3) -> ffi::c_int {
stub!();
pub unsafe extern "C" fn sqlite3_get_autocommit(db: *mut sqlite3) -> ffi::c_int {
if db.is_null() {
return 1;
}
let db: &mut sqlite3 = &mut *db;
let inner = db.inner.lock().unwrap();
if inner.conn.get_auto_commit() {
1
} else {
0
}
}
#[no_mangle]

View File

@@ -71,6 +71,7 @@ extern "C" {
fn sqlite3_column_blob(stmt: *mut sqlite3_stmt, idx: i32) -> *const libc::c_void;
fn sqlite3_column_type(stmt: *mut sqlite3_stmt, idx: i32) -> i32;
fn sqlite3_column_decltype(stmt: *mut sqlite3_stmt, idx: i32) -> *const libc::c_char;
fn sqlite3_get_autocommit(db: *mut sqlite3) -> i32;
}
const SQLITE_OK: i32 = 0;
@@ -986,6 +987,85 @@ mod tests {
}
}
#[test]
fn test_get_autocommit() {
unsafe {
let temp_file = tempfile::NamedTempFile::with_suffix(".db").unwrap();
let path = std::ffi::CString::new(temp_file.path().to_str().unwrap()).unwrap();
let mut db = ptr::null_mut();
assert_eq!(sqlite3_open(path.as_ptr(), &mut db), SQLITE_OK);
// Should be in autocommit mode by default
assert_eq!(sqlite3_get_autocommit(db), 1);
// Begin a transaction
let mut stmt = ptr::null_mut();
assert_eq!(
sqlite3_prepare_v2(db, c"BEGIN".as_ptr(), -1, &mut stmt, ptr::null_mut()),
SQLITE_OK
);
assert_eq!(sqlite3_step(stmt), SQLITE_DONE);
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
// Should NOT be in autocommit mode during transaction
assert_eq!(sqlite3_get_autocommit(db), 0);
// Create a table within the transaction
let mut stmt = ptr::null_mut();
assert_eq!(
sqlite3_prepare_v2(
db,
c"CREATE TABLE test (id INTEGER PRIMARY KEY)".as_ptr(),
-1,
&mut stmt,
ptr::null_mut()
),
SQLITE_OK
);
assert_eq!(sqlite3_step(stmt), SQLITE_DONE);
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
// Still not in autocommit mode
assert_eq!(sqlite3_get_autocommit(db), 0);
// Commit the transaction
let mut stmt = ptr::null_mut();
assert_eq!(
sqlite3_prepare_v2(db, c"COMMIT".as_ptr(), -1, &mut stmt, ptr::null_mut()),
SQLITE_OK
);
assert_eq!(sqlite3_step(stmt), SQLITE_DONE);
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
// Should be back in autocommit mode after commit
assert_eq!(sqlite3_get_autocommit(db), 1);
// Test with ROLLBACK
let mut stmt = ptr::null_mut();
assert_eq!(
sqlite3_prepare_v2(db, c"BEGIN".as_ptr(), -1, &mut stmt, ptr::null_mut()),
SQLITE_OK
);
assert_eq!(sqlite3_step(stmt), SQLITE_DONE);
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
assert_eq!(sqlite3_get_autocommit(db), 0);
let mut stmt = ptr::null_mut();
assert_eq!(
sqlite3_prepare_v2(db, c"ROLLBACK".as_ptr(), -1, &mut stmt, ptr::null_mut()),
SQLITE_OK
);
assert_eq!(sqlite3_step(stmt), SQLITE_DONE);
assert_eq!(sqlite3_finalize(stmt), SQLITE_OK);
// Should be back in autocommit mode after rollback
assert_eq!(sqlite3_get_autocommit(db), 1);
assert_eq!(sqlite3_close(db), SQLITE_OK);
}
}
#[test]
fn test_wal_checkpoint() {
let temp_file = tempfile::NamedTempFile::with_suffix(".db").unwrap();