Remove obsolete codes and comments

Minimal SQLite version supported by rusqlite is 3.14
This commit is contained in:
gwenn 2024-02-25 14:26:47 +01:00
parent 059b7d06ac
commit cd5b780505
4 changed files with 22 additions and 113 deletions

View File

@ -94,17 +94,14 @@ features](https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-s
allows loading dynamic library-based SQLite extensions.
* `loadable_extension` to program [loadable extension](https://sqlite.org/loadext.html) in Rust.
* [`backup`](https://docs.rs/rusqlite/~0/rusqlite/backup/index.html)
allows use of SQLite's online backup API. Note: This feature requires SQLite 3.6.11 or later.
allows use of SQLite's online backup API.
* [`functions`](https://docs.rs/rusqlite/~0/rusqlite/functions/index.html)
allows you to load Rust closures into SQLite connections for use in queries.
Note: This feature requires SQLite 3.7.3 or later.
* `window` for [window function](https://www.sqlite.org/windowfunctions.html) support (`fun(...) OVER ...`). (Implies `functions`.)
* [`trace`](https://docs.rs/rusqlite/~0/rusqlite/trace/index.html)
allows hooks into SQLite's tracing and profiling APIs. Note: This feature
requires SQLite 3.6.23 or later.
allows hooks into SQLite's tracing and profiling APIs.
* [`blob`](https://docs.rs/rusqlite/~0/rusqlite/blob/index.html)
gives `std::io::{Read, Write, Seek}` access to SQL BLOBs. Note: This feature
requires SQLite 3.7.4 or later.
gives `std::io::{Read, Write, Seek}` access to SQL BLOBs.
* [`limits`](https://docs.rs/rusqlite/~0/rusqlite/struct.Connection.html#method.limit)
allows you to set and retrieve SQLite's per connection limits.
* `chrono` implements [`FromSql`](https://docs.rs/rusqlite/~0/rusqlite/types/trait.FromSql.html)

View File

@ -4,7 +4,6 @@ use std::os::raw::{c_char, c_int};
use std::path::Path;
use std::ptr;
use std::str;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Mutex};
use super::ffi;
@ -13,7 +12,6 @@ use super::{Connection, InterruptHandle, OpenFlags, PrepFlags, Result};
use crate::error::{error_from_handle, error_from_sqlite_code, error_with_offset, Error};
use crate::raw_statement::RawStatement;
use crate::statement::Statement;
use crate::version::version_number;
pub struct InnerConnection {
pub db: *mut ffi::sqlite3,
@ -67,21 +65,6 @@ impl InnerConnection {
) -> Result<InnerConnection> {
ensure_safe_sqlite_threading_mode()?;
// Replicate the check for sane open flags from SQLite, because the check in
// SQLite itself wasn't added until version 3.7.3.
debug_assert_eq!(1 << OpenFlags::SQLITE_OPEN_READ_ONLY.bits(), 0x02);
debug_assert_eq!(1 << OpenFlags::SQLITE_OPEN_READ_WRITE.bits(), 0x04);
debug_assert_eq!(
1 << (OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE).bits(),
0x40
);
if (1 << (flags.bits() & 0x7)) & 0x46 == 0 {
return Err(Error::SqliteFailure(
ffi::Error::new(ffi::SQLITE_MISUSE),
None,
));
}
let z_vfs = match vfs {
Some(c_vfs) => c_vfs.as_ptr(),
None => ptr::null(),
@ -390,11 +373,6 @@ impl Drop for InnerConnection {
}
}
#[cfg(not(any(target_arch = "wasm32", feature = "loadable_extension")))]
static SQLITE_INIT: std::sync::Once = std::sync::Once::new();
pub static BYPASS_SQLITE_INIT: AtomicBool = AtomicBool::new(false);
// threading mode checks are not necessary (and do not work) on target
// platforms that do not have threading (such as webassembly)
#[cfg(target_arch = "wasm32")]
@ -412,51 +390,21 @@ fn ensure_safe_sqlite_threading_mode() -> Result<()> {
// Now we know SQLite is _capable_ of being in Multi-thread of Serialized mode,
// but it's possible someone configured it to be in Single-thread mode
// before calling into us. That would mean we're exposing an unsafe API via
// a safe one (in Rust terminology), which is no good. We have two options
// to protect against this, depending on the version of SQLite we're linked
// with:
// a safe one (in Rust terminology).
//
// 1. If we're on 3.7.0 or later, we can ask SQLite for a mutex and check for
// the magic value 8. This isn't documented, but it's what SQLite
// returns for its mutex allocation function in Single-thread mode.
// 2. If we're prior to SQLite 3.7.0, AFAIK there's no way to check the
// threading mode. The check we perform for >= 3.7.0 will segfault.
// Instead, we insist on being able to call sqlite3_config and
// sqlite3_initialize ourself, ensuring we know the threading
// mode. This will fail if someone else has already initialized SQLite
// even if they initialized it safely. That's not ideal either, which is
// why we expose bypass_sqlite_initialization above.
if version_number() >= 3_007_000 {
const SQLITE_SINGLETHREADED_MUTEX_MAGIC: usize = 8;
let is_singlethreaded = unsafe {
let mutex_ptr = ffi::sqlite3_mutex_alloc(0);
let is_singlethreaded = mutex_ptr as usize == SQLITE_SINGLETHREADED_MUTEX_MAGIC;
ffi::sqlite3_mutex_free(mutex_ptr);
is_singlethreaded
};
if is_singlethreaded {
Err(Error::SqliteSingleThreadedMode)
} else {
Ok(())
}
// We can ask SQLite for a mutex and check for
// the magic value 8. This isn't documented, but it's what SQLite
// returns for its mutex allocation function in Single-thread mode.
const SQLITE_SINGLETHREADED_MUTEX_MAGIC: usize = 8;
let is_singlethreaded = unsafe {
let mutex_ptr = ffi::sqlite3_mutex_alloc(0);
let is_singlethreaded = mutex_ptr as usize == SQLITE_SINGLETHREADED_MUTEX_MAGIC;
ffi::sqlite3_mutex_free(mutex_ptr);
is_singlethreaded
};
if is_singlethreaded {
Err(Error::SqliteSingleThreadedMode)
} else {
#[cfg(not(feature = "loadable_extension"))]
SQLITE_INIT.call_once(|| {
use std::sync::atomic::Ordering;
if BYPASS_SQLITE_INIT.load(Ordering::Relaxed) {
return;
}
unsafe {
assert!(ffi::sqlite3_config(ffi::SQLITE_CONFIG_MULTITHREAD) == ffi::SQLITE_OK && ffi::sqlite3_initialize() == ffi::SQLITE_OK,
"Could not ensure safe initialization of SQLite.\n\
To fix this, either:\n\
* Upgrade SQLite to at least version 3.7.0\n\
* Ensure that SQLite has been initialized in Multi-thread or Serialized mode and call\n\
rusqlite::bypass_sqlite_initialization() prior to your first connection attempt."
);
}
});
Ok(())
}
}

View File

@ -65,11 +65,10 @@ use std::os::raw::{c_char, c_int};
use std::path::Path;
use std::result;
use std::str;
use std::sync::atomic::Ordering;
use std::sync::{Arc, Mutex};
use crate::cache::StatementCache;
use crate::inner_connection::{InnerConnection, BYPASS_SQLITE_INIT};
use crate::inner_connection::InnerConnection;
use crate::raw_statement::RawStatement;
use crate::types::ValueRef;
@ -1196,29 +1195,6 @@ bitflags::bitflags! {
}
}
/// rusqlite's check for a safe SQLite threading mode requires SQLite 3.7.0 or
/// later. If you are running against a SQLite older than that, rusqlite
/// attempts to ensure safety by performing configuration and initialization of
/// SQLite itself the first time you
/// attempt to open a connection. By default, rusqlite panics if that
/// initialization fails, since that could mean SQLite has been initialized in
/// single-thread mode.
///
/// If you are encountering that panic _and_ can ensure that SQLite has been
/// initialized in either multi-thread or serialized mode, call this function
/// prior to attempting to open a connection and rusqlite's initialization
/// process will by skipped.
///
/// # Safety
///
/// This function is unsafe because if you call it and SQLite has actually been
/// configured to run in single-thread mode,
/// you may encounter memory errors or data corruption or any number of terrible
/// things that should not be possible when you're using Rust.
pub unsafe fn bypass_sqlite_initialization() {
BYPASS_SQLITE_INIT.store(true, Ordering::Relaxed);
}
/// Allows interrupting a long-running computation.
pub struct InterruptHandle {
db_lock: Arc<Mutex<*mut ffi::sqlite3>>,
@ -1756,12 +1732,6 @@ mod test {
#[test]
fn test_notnull_constraint_error() -> Result<()> {
// extended error codes for constraints were added in SQLite 3.7.16; if we're
// running on our bundled version, we know the extended error code exists.
fn check_extended_code(extended_code: c_int) {
assert_eq!(extended_code, ffi::SQLITE_CONSTRAINT_NOTNULL);
}
let db = Connection::open_in_memory()?;
db.execute_batch("CREATE TABLE foo(x NOT NULL)")?;
@ -1770,7 +1740,7 @@ mod test {
match result.unwrap_err() {
Error::SqliteFailure(err, _) => {
assert_eq!(err.code, ErrorCode::ConstraintViolation);
check_extended_code(err.extended_code);
assert_eq!(err.extended_code, ffi::SQLITE_CONSTRAINT_NOTNULL);
}
err => panic!("Unexpected error {err}"),
}

View File

@ -148,17 +148,11 @@ mod test {
db.set_limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER, 99);
assert_eq!(99, db.limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER));
// SQLITE_LIMIT_TRIGGER_DEPTH was added in SQLite 3.6.18.
if crate::version_number() >= 3_006_018 {
db.set_limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH, 32);
assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH));
}
db.set_limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH, 32);
assert_eq!(32, db.limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH));
// SQLITE_LIMIT_WORKER_THREADS was added in SQLite 3.8.7.
if crate::version_number() >= 3_008_007 {
db.set_limit(Limit::SQLITE_LIMIT_WORKER_THREADS, 2);
assert_eq!(2, db.limit(Limit::SQLITE_LIMIT_WORKER_THREADS));
}
db.set_limit(Limit::SQLITE_LIMIT_WORKER_THREADS, 2);
assert_eq!(2, db.limit(Limit::SQLITE_LIMIT_WORKER_THREADS));
Ok(())
}
}