diff --git a/sqlite3/Cargo.toml b/sqlite3/Cargo.toml index 444698d66..8d17ad77c 100644 --- a/sqlite3/Cargo.toml +++ b/sqlite3/Cargo.toml @@ -7,10 +7,12 @@ authors.workspace = true edition.workspace = true license.workspace = true repository.workspace = true +build = "build.rs" [features] capi = [] lfs = [] +sqlite3 = [] [package.metadata.dist] dist = true @@ -25,6 +27,11 @@ libc = "0.2.169" limbo_core = { path = "../core" } log = "0.4.22" - [package.metadata.capi.header] name = "sqlite3.h" + +[[test]] +name = "compat" +path = "tests/compat/mod.rs" + +[build-dependencies] diff --git a/sqlite3/build.rs b/sqlite3/build.rs new file mode 100644 index 000000000..c00f4d679 --- /dev/null +++ b/sqlite3/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rustc-link-search=native=target/debug"); +} diff --git a/sqlite3/src/lib.rs b/sqlite3/src/lib.rs index f54e6bdb2..7e43c1ad1 100644 --- a/sqlite3/src/lib.rs +++ b/sqlite3/src/lib.rs @@ -1083,187 +1083,3 @@ pub unsafe extern "C" fn sqlite3_wal_checkpoint_v2( } SQLITE_OK } - -#[cfg(test)] -mod tests { - use super::*; - use std::ptr; - - #[test] - fn test_libversion() { - unsafe { - let version = sqlite3_libversion(); - assert!(!version.is_null()); - } - } - - #[test] - fn test_libversion_number() { - unsafe { - let version_num = sqlite3_libversion_number(); - assert_eq!(version_num, 3042000); - } - } - - #[test] - fn test_open_misuse() { - unsafe { - let mut db = ptr::null_mut(); - assert_eq!(sqlite3_open(ptr::null(), &mut db), SQLITE_MISUSE); - } - } - - #[test] - fn test_open_not_found() { - unsafe { - let mut db = ptr::null_mut(); - assert_eq!( - sqlite3_open(b"not-found/local.db\0".as_ptr() as *const i8, &mut db), - SQLITE_CANTOPEN - ); - } - } - - #[test] - #[ignore] - fn test_open_existing() { - unsafe { - let mut db = ptr::null_mut(); - assert_eq!( - sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), - SQLITE_OK - ); - assert_eq!(sqlite3_close(db), SQLITE_OK); - } - } - - #[test] - fn test_close() { - unsafe { - assert_eq!(sqlite3_close(ptr::null_mut()), SQLITE_OK); - } - } - - #[test] - #[ignore] - fn test_prepare_misuse() { - unsafe { - let mut db = ptr::null_mut(); - assert_eq!( - sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), - SQLITE_OK - ); - - let mut stmt = ptr::null_mut(); - assert_eq!( - sqlite3_prepare_v2( - db, - b"SELECT 1\0".as_ptr() as *const i8, - -1, - &mut stmt, - ptr::null_mut() - ), - SQLITE_OK - ); - - assert_eq!(sqlite3_finalize(stmt), SQLITE_OK); - assert_eq!(sqlite3_close(db), SQLITE_OK); - } - } - - #[test] - #[ignore] - fn test_wal_checkpoint() { - unsafe { - // Test with NULL db handle - assert_eq!( - sqlite3_wal_checkpoint(ptr::null_mut(), ptr::null()), - SQLITE_MISUSE - ); - - // Test with valid db - let mut db = ptr::null_mut(); - assert_eq!( - sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), - SQLITE_OK - ); - assert_eq!(sqlite3_wal_checkpoint(db, ptr::null()), SQLITE_OK); - assert_eq!(sqlite3_close(db), SQLITE_OK); - } - } - - #[test] - #[ignore] - fn test_wal_checkpoint_v2() { - unsafe { - // Test with NULL db handle - assert_eq!( - sqlite3_wal_checkpoint_v2( - ptr::null_mut(), - ptr::null(), - SQLITE_CHECKPOINT_PASSIVE, - ptr::null_mut(), - ptr::null_mut() - ), - SQLITE_MISUSE - ); - - // Test with valid db - let mut db = ptr::null_mut(); - assert_eq!( - sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), - SQLITE_OK - ); - - let mut log_size = 0; - let mut checkpoint_count = 0; - - // Test different checkpoint modes - assert_eq!( - sqlite3_wal_checkpoint_v2( - db, - ptr::null(), - SQLITE_CHECKPOINT_PASSIVE, - &mut log_size, - &mut checkpoint_count - ), - SQLITE_OK - ); - - assert_eq!( - sqlite3_wal_checkpoint_v2( - db, - ptr::null(), - SQLITE_CHECKPOINT_FULL, - &mut log_size, - &mut checkpoint_count - ), - SQLITE_OK - ); - - assert_eq!( - sqlite3_wal_checkpoint_v2( - db, - ptr::null(), - SQLITE_CHECKPOINT_RESTART, - &mut log_size, - &mut checkpoint_count - ), - SQLITE_OK - ); - - assert_eq!( - sqlite3_wal_checkpoint_v2( - db, - ptr::null(), - SQLITE_CHECKPOINT_TRUNCATE, - &mut log_size, - &mut checkpoint_count - ), - SQLITE_OK - ); - - assert_eq!(sqlite3_close(db), SQLITE_OK); - } - } -} diff --git a/sqlite3/tests/compat/mod.rs b/sqlite3/tests/compat/mod.rs new file mode 100644 index 000000000..1266789da --- /dev/null +++ b/sqlite3/tests/compat/mod.rs @@ -0,0 +1,222 @@ +#[allow(non_camel_case_types)] +use std::ptr; + +#[repr(C)] +struct sqlite3 { + _private: [u8; 0], +} + +#[repr(C)] +struct sqlite3_stmt { + _private: [u8; 0], +} + +#[cfg_attr(not(feature = "sqlite3"), link(name = "limbo_sqlite3"))] +#[cfg_attr(feature = "sqlite3", link(name = "sqlite3"))] +extern "C" { + fn sqlite3_libversion() -> *const libc::c_char; + fn sqlite3_libversion_number() -> i32; + fn sqlite3_close(db: *mut sqlite3) -> i32; + fn sqlite3_open(filename: *const libc::c_char, db: *mut *mut sqlite3) -> i32; + fn sqlite3_prepare_v2( + db: *mut sqlite3, + sql: *const libc::c_char, + n_bytes: i32, + stmt: *mut *mut sqlite3_stmt, + tail: *mut *const libc::c_char, + ) -> i32; + fn sqlite3_finalize(stmt: *mut sqlite3_stmt) -> i32; + fn sqlite3_wal_checkpoint(db: *mut sqlite3, db_name: *const libc::c_char) -> i32; + fn sqlite3_wal_checkpoint_v2( + db: *mut sqlite3, + db_name: *const libc::c_char, + mode: i32, + log_size: *mut i32, + checkpoint_count: *mut i32, + ) -> i32; +} + +const SQLITE_OK: i32 = 0; +const SQLITE_MISUSE: i32 = 21; +const SQLITE_CANTOPEN: i32 = 14; +const SQLITE_CHECKPOINT_PASSIVE: i32 = 0; +const SQLITE_CHECKPOINT_FULL: i32 = 1; +const SQLITE_CHECKPOINT_RESTART: i32 = 2; +const SQLITE_CHECKPOINT_TRUNCATE: i32 = 3; + +#[test] +fn test_libversion() { + unsafe { + let version = sqlite3_libversion(); + assert!(!version.is_null()); + } +} + +#[test] +fn test_libversion_number() { + unsafe { + let version_num = sqlite3_libversion_number(); + assert_eq!(version_num, 3042000); + } +} + +#[test] +fn test_open_misuse() { + unsafe { + let mut db = ptr::null_mut(); + assert_eq!(sqlite3_open(ptr::null(), &mut db), SQLITE_MISUSE); + } +} + +#[test] +fn test_open_not_found() { + unsafe { + let mut db = ptr::null_mut(); + assert_eq!( + sqlite3_open(b"not-found/local.db\0".as_ptr() as *const i8, &mut db), + SQLITE_CANTOPEN + ); + } +} + +#[test] +fn test_open_existing() { + unsafe { + let mut db = ptr::null_mut(); + assert_eq!( + sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), + SQLITE_OK + ); + assert_eq!(sqlite3_close(db), SQLITE_OK); + } +} + +#[test] +fn test_close() { + unsafe { + assert_eq!(sqlite3_close(ptr::null_mut()), SQLITE_OK); + } +} + +#[test] +#[ignore] +fn test_prepare_misuse() { + unsafe { + let mut db = ptr::null_mut(); + assert_eq!( + sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), + SQLITE_OK + ); + + let mut stmt = ptr::null_mut(); + assert_eq!( + sqlite3_prepare_v2( + db, + b"SELECT 1\0".as_ptr() as *const i8, + -1, + &mut stmt, + ptr::null_mut() + ), + SQLITE_OK + ); + + assert_eq!(sqlite3_finalize(stmt), SQLITE_OK); + assert_eq!(sqlite3_close(db), SQLITE_OK); + } +} + +#[test] +#[ignore] +fn test_wal_checkpoint() { + unsafe { + // Test with NULL db handle + assert_eq!( + sqlite3_wal_checkpoint(ptr::null_mut(), ptr::null()), + SQLITE_MISUSE + ); + + // Test with valid db + let mut db = ptr::null_mut(); + assert_eq!( + sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), + SQLITE_OK + ); + assert_eq!(sqlite3_wal_checkpoint(db, ptr::null()), SQLITE_OK); + assert_eq!(sqlite3_close(db), SQLITE_OK); + } +} + +#[test] +#[ignore] +fn test_wal_checkpoint_v2() { + unsafe { + // Test with NULL db handle + assert_eq!( + sqlite3_wal_checkpoint_v2( + ptr::null_mut(), + ptr::null(), + SQLITE_CHECKPOINT_PASSIVE, + ptr::null_mut(), + ptr::null_mut() + ), + SQLITE_MISUSE + ); + + // Test with valid db + let mut db = ptr::null_mut(); + assert_eq!( + sqlite3_open(b"../testing/testing.db\0".as_ptr() as *const i8, &mut db), + SQLITE_OK + ); + + let mut log_size = 0; + let mut checkpoint_count = 0; + + // Test different checkpoint modes + assert_eq!( + sqlite3_wal_checkpoint_v2( + db, + ptr::null(), + SQLITE_CHECKPOINT_PASSIVE, + &mut log_size, + &mut checkpoint_count + ), + SQLITE_OK + ); + + assert_eq!( + sqlite3_wal_checkpoint_v2( + db, + ptr::null(), + SQLITE_CHECKPOINT_FULL, + &mut log_size, + &mut checkpoint_count + ), + SQLITE_OK + ); + + assert_eq!( + sqlite3_wal_checkpoint_v2( + db, + ptr::null(), + SQLITE_CHECKPOINT_RESTART, + &mut log_size, + &mut checkpoint_count + ), + SQLITE_OK + ); + + assert_eq!( + sqlite3_wal_checkpoint_v2( + db, + ptr::null(), + SQLITE_CHECKPOINT_TRUNCATE, + &mut log_size, + &mut checkpoint_count + ), + SQLITE_OK + ); + + assert_eq!(sqlite3_close(db), SQLITE_OK); + } +}