Remove most of the code using feature=bundled as a version check

This commit is contained in:
Thom Chiovoloni 2020-01-14 08:11:36 -08:00
parent a788d40f10
commit c70d148542
11 changed files with 53 additions and 38 deletions

View File

@ -33,7 +33,7 @@ collation = []
functions = ["libsqlite3-sys/min_sqlite_version_3_7_7"] functions = ["libsqlite3-sys/min_sqlite_version_3_7_7"]
# sqlite3_log: 3.6.23 (2010-03-09) # sqlite3_log: 3.6.23 (2010-03-09)
trace = ["libsqlite3-sys/min_sqlite_version_3_6_23"] trace = ["libsqlite3-sys/min_sqlite_version_3_6_23"]
bundled = ["libsqlite3-sys/bundled"] bundled = ["libsqlite3-sys/bundled", "modern_sqlite"]
buildtime_bindgen = ["libsqlite3-sys/buildtime_bindgen"] buildtime_bindgen = ["libsqlite3-sys/buildtime_bindgen"]
limits = [] limits = []
hooks = [] hooks = []
@ -55,6 +55,7 @@ window = ["functions"]
series = ["vtab"] series = ["vtab"]
# check for invalid query. # check for invalid query.
extra_check = [] extra_check = []
modern_sqlite = ["libsqlite3-sys/bundled_bindings"]
[dependencies] [dependencies]
time = "0.1.0" time = "0.1.0"
@ -93,7 +94,7 @@ name = "deny_single_threaded_sqlite_config"
name = "vtab" name = "vtab"
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = [ "backup", "blob", "chrono", "collation", "functions", "limits", "load_extension", "serde_json", "trace", "url", "vtab", "window" ] features = [ "backup", "blob", "chrono", "collation", "functions", "limits", "load_extension", "serde_json", "trace", "url", "vtab", "window", "modern_sqlite" ]
all-features = false all-features = false
no-default-features = true no-default-features = true
default-target = "x86_64-unknown-linux-gnu" default-target = "x86_64-unknown-linux-gnu"

View File

@ -165,6 +165,12 @@ bundled version of SQLite. If you need other specific pregenerated binding
versions, please file an issue. If you want to run `bindgen` at buildtime to versions, please file an issue. If you want to run `bindgen` at buildtime to
produce your own bindings, use the `buildtime_bindgen` Cargo feature. produce your own bindings, use the `buildtime_bindgen` Cargo feature.
If you enable the `modern_sqlite` feature, we'll use the bindings we would have
included with the bundled build. You generally should have `buildtime_bindgen`
enabled if you turn this on, as otherwise you'll need to keep the version of
SQLite you link with in sync with what rusqlite would have bundled, (usually the
most recent release of sqlite). Failing to do this will cause a runtime error.
## Author ## Author
John Gallagher, johnkgallagher@gmail.com John Gallagher, johnkgallagher@gmail.com

View File

@ -13,14 +13,17 @@ categories = ["external-ffi-bindings"]
[features] [features]
default = ["min_sqlite_version_3_6_8"] default = ["min_sqlite_version_3_6_8"]
bundled = ["cc"] bundled = ["cc", "bundled_bindings"]
bundled-windows = ["cc"] bundled-windows = ["cc", "bundled_bindings"]
buildtime_bindgen = ["bindgen", "pkg-config", "vcpkg"] buildtime_bindgen = ["bindgen", "pkg-config", "vcpkg"]
sqlcipher = [] sqlcipher = []
min_sqlite_version_3_6_8 = ["pkg-config", "vcpkg"] min_sqlite_version_3_6_8 = ["pkg-config", "vcpkg"]
min_sqlite_version_3_6_23 = ["pkg-config", "vcpkg"] min_sqlite_version_3_6_23 = ["pkg-config", "vcpkg"]
min_sqlite_version_3_7_7 = ["pkg-config", "vcpkg"] min_sqlite_version_3_7_7 = ["pkg-config", "vcpkg"]
min_sqlite_version_3_7_16 = ["pkg-config", "vcpkg"] min_sqlite_version_3_7_16 = ["pkg-config", "vcpkg"]
# Bundle only the bindings file. Note that this does nothing if
# `buildtime_bindgen` is enabled.
bundled_bindings = []
# sqlite3_unlock_notify >= 3.6.12 # sqlite3_unlock_notify >= 3.6.12
unlock_notify = [] unlock_notify = []
# 3.13.0 # 3.13.0

View File

@ -166,18 +166,17 @@ mod build_linked {
pub fn main(_out_dir: &str, out_path: &Path) { pub fn main(_out_dir: &str, out_path: &Path) {
let header = find_sqlite(); let header = find_sqlite();
if cfg!(any( if cfg!(any(
feature = "bundled_bindings",
feature = "bundled", feature = "bundled",
all(windows, feature = "bundled-windows") all(windows, feature = "bundled-windows")
)) && !cfg!(feature = "buildtime_bindgen") )) && !cfg!(feature = "buildtime_bindgen")
{ {
// We can only get here if `bundled` and `sqlcipher` were both // Generally means the `bundled_bindings` feature is enabled
// specified (and `builtime_bindgen` was not). In order to keep // (there's also an edge case where we get here involving
// `rusqlite` relatively clean we hide the fact that `bundled` can // sqlcipher). In either case most users are better off with turning
// be ignored in some cases, and just use the bundled bindings, even // on buildtime_bindgen instead, but this is still supported as we
// though the library we found might not match their version. // have runtime version checks and there are good reasons to not
// Ideally we'd perform a version check here, but doing so is rather // want to run bindgen.
// tricky, since we might not have access to executables (and
// moreover, we might be cross compiling).
std::fs::copy("sqlite3/bindgen_bundled_version.rs", out_path) std::fs::copy("sqlite3/bindgen_bundled_version.rs", out_path)
.expect("Could not copy bindings to output directory"); .expect("Could not copy bindings to output directory");
} else { } else {

View File

@ -81,11 +81,11 @@ unsafe fn report_error(ctx: *mut sqlite3_context, err: &Error) {
// an explicit feature check for that, and this doesn't really warrant one. // an explicit feature check for that, and this doesn't really warrant one.
// We'll use the extended code if we're on the bundled version (since it's // We'll use the extended code if we're on the bundled version (since it's
// at least 3.17.0) and the normal constraint error code if not. // at least 3.17.0) and the normal constraint error code if not.
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
fn constraint_error_code() -> i32 { fn constraint_error_code() -> i32 {
ffi::SQLITE_CONSTRAINT_FUNCTION ffi::SQLITE_CONSTRAINT_FUNCTION
} }
#[cfg(not(feature = "bundled"))] #[cfg(not(feature = "modern_sqlite"))]
fn constraint_error_code() -> i32 { fn constraint_error_code() -> i32 {
ffi::SQLITE_CONSTRAINT ffi::SQLITE_CONSTRAINT
} }

View File

@ -281,7 +281,7 @@ impl InnerConnection {
unsafe { ffi::sqlite3_get_autocommit(self.db()) != 0 } unsafe { ffi::sqlite3_get_autocommit(self.db()) != 0 }
} }
#[cfg(feature = "bundled")] // 3.8.6 #[cfg(feature = "modern_sqlite")] // 3.8.6
pub fn is_busy(&self) -> bool { pub fn is_busy(&self) -> bool {
let db = self.db(); let db = self.db();
unsafe { unsafe {

View File

@ -295,7 +295,7 @@ pub enum DatabaseName<'a> {
feature = "backup", feature = "backup",
feature = "blob", feature = "blob",
feature = "session", feature = "session",
feature = "bundled" feature = "modern_sqlite"
))] ))]
impl DatabaseName<'_> { impl DatabaseName<'_> {
fn to_cstring(&self) -> Result<CString> { fn to_cstring(&self) -> Result<CString> {
@ -750,7 +750,7 @@ impl Connection {
} }
/// Determine if all associated prepared statements have been reset. /// Determine if all associated prepared statements have been reset.
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")] // 3.8.6
pub fn is_busy(&self) -> bool { pub fn is_busy(&self) -> bool {
self.db.borrow().is_busy() self.db.borrow().is_busy()
} }
@ -847,7 +847,7 @@ impl InterruptHandle {
} }
} }
#[cfg(feature = "bundled")] // 3.7.10 #[cfg(feature = "modern_sqlite")] // 3.7.10
unsafe fn db_filename(db: *mut ffi::sqlite3) -> Option<PathBuf> { unsafe fn db_filename(db: *mut ffi::sqlite3) -> Option<PathBuf> {
let db_name = DatabaseName::Main.to_cstring().unwrap(); let db_name = DatabaseName::Main.to_cstring().unwrap();
let db_filename = ffi::sqlite3_db_filename(db, db_name.as_ptr()); let db_filename = ffi::sqlite3_db_filename(db, db_name.as_ptr());
@ -857,7 +857,7 @@ unsafe fn db_filename(db: *mut ffi::sqlite3) -> Option<PathBuf> {
CStr::from_ptr(db_filename).to_str().ok().map(PathBuf::from) CStr::from_ptr(db_filename).to_str().ok().map(PathBuf::from)
} }
} }
#[cfg(not(feature = "bundled"))] #[cfg(not(feature = "modern_sqlite"))]
unsafe fn db_filename(_: *mut ffi::sqlite3) -> Option<PathBuf> { unsafe fn db_filename(_: *mut ffi::sqlite3) -> Option<PathBuf> {
None None
} }
@ -1302,7 +1302,7 @@ mod test {
} }
#[test] #[test]
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
fn test_is_busy() { fn test_is_busy() {
let db = checked_memory_handle(); let db = checked_memory_handle();
assert!(!db.is_busy()); assert!(!db.is_busy());
@ -1331,11 +1331,11 @@ mod test {
fn test_notnull_constraint_error() { fn test_notnull_constraint_error() {
// extended error codes for constraints were added in SQLite 3.7.16; if we're // 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. // running on our bundled version, we know the extended error code exists.
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
fn check_extended_code(extended_code: c_int) { fn check_extended_code(extended_code: c_int) {
assert_eq!(extended_code, ffi::SQLITE_CONSTRAINT_NOTNULL); assert_eq!(extended_code, ffi::SQLITE_CONSTRAINT_NOTNULL);
} }
#[cfg(not(feature = "bundled"))] #[cfg(not(feature = "modern_sqlite"))]
fn check_extended_code(_extended_code: c_int) {} fn check_extended_code(_extended_code: c_int) {}
let db = checked_memory_handle(); let db = checked_memory_handle();

View File

@ -326,7 +326,7 @@ mod test {
} }
#[test] #[test]
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
fn pragma_func_query_value() { fn pragma_func_query_value() {
use crate::NO_PARAMS; use crate::NO_PARAMS;
@ -379,7 +379,7 @@ mod test {
} }
#[test] #[test]
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
fn pragma_func() { fn pragma_func() {
let db = Connection::open_in_memory().unwrap(); let db = Connection::open_in_memory().unwrap();
let mut table_info = db.prepare("SELECT * FROM pragma_table_info(?)").unwrap(); let mut table_info = db.prepare("SELECT * FROM pragma_table_info(?)").unwrap();

View File

@ -117,13 +117,13 @@ impl RawStatement {
r r
} }
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")] // 3.7.4
pub fn readonly(&self) -> bool { pub fn readonly(&self) -> bool {
unsafe { ffi::sqlite3_stmt_readonly(self.0) != 0 } unsafe { ffi::sqlite3_stmt_readonly(self.0) != 0 }
} }
/// `CStr` must be freed /// `CStr` must be freed
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")] // 3.14.0
pub unsafe fn expanded_sql(&self) -> Option<&CStr> { pub unsafe fn expanded_sql(&self) -> Option<&CStr> {
let ptr = ffi::sqlite3_expanded_sql(self.0); let ptr = ffi::sqlite3_expanded_sql(self.0);
if ptr.is_null() { if ptr.is_null() {

View File

@ -533,13 +533,13 @@ impl Statement<'_> {
self.conn.decode_result(stmt.finalize()) self.conn.decode_result(stmt.finalize())
} }
#[cfg(not(feature = "bundled"))] #[cfg(not(feature = "modern_sqlite"))]
#[inline] #[inline]
fn check_readonly(&self) -> Result<()> { fn check_readonly(&self) -> Result<()> {
Ok(()) Ok(())
} }
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
#[inline] #[inline]
fn check_readonly(&self) -> Result<()> { fn check_readonly(&self) -> Result<()> {
/*if !self.stmt.readonly() { does not work for PRAGMA /*if !self.stmt.readonly() { does not work for PRAGMA
@ -548,7 +548,7 @@ impl Statement<'_> {
Ok(()) Ok(())
} }
#[cfg(all(feature = "bundled", feature = "extra_check"))] #[cfg(all(feature = "modern_sqlite", feature = "extra_check"))]
#[inline] #[inline]
fn check_update(&self) -> Result<()> { fn check_update(&self) -> Result<()> {
if self.column_count() > 0 || self.stmt.readonly() { if self.column_count() > 0 || self.stmt.readonly() {
@ -557,7 +557,7 @@ impl Statement<'_> {
Ok(()) Ok(())
} }
#[cfg(all(not(feature = "bundled"), feature = "extra_check"))] #[cfg(all(not(feature = "modern_sqlite"), feature = "extra_check"))]
#[inline] #[inline]
fn check_update(&self) -> Result<()> { fn check_update(&self) -> Result<()> {
if self.column_count() > 0 { if self.column_count() > 0 {
@ -574,7 +574,7 @@ impl Statement<'_> {
/// Returns a string containing the SQL text of prepared statement with /// Returns a string containing the SQL text of prepared statement with
/// bound parameters expanded. /// bound parameters expanded.
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
pub fn expanded_sql(&self) -> Option<String> { pub fn expanded_sql(&self) -> Option<String> {
unsafe { unsafe {
match self.stmt.expanded_sql() { match self.stmt.expanded_sql() {
@ -1019,7 +1019,7 @@ mod test {
} }
#[test] #[test]
#[cfg(feature = "bundled")] #[cfg(feature = "modern_sqlite")]
fn test_expanded_sql() { fn test_expanded_sql() {
let db = Connection::open_in_memory().unwrap(); let db = Connection::open_in_memory().unwrap();
let stmt = db.prepare("SELECT ?").unwrap(); let stmt = db.prepare("SELECT ?").unwrap();

View File

@ -70,6 +70,14 @@ pub struct Module<T: VTab> {
unsafe impl<T: VTab> Send for Module<T> {} unsafe impl<T: VTab> Send for Module<T> {}
unsafe impl<T: VTab> Sync for Module<T> {} unsafe impl<T: VTab> Sync for Module<T> {}
// Used as a trailing initializer for sqlite3_module -- this way we avoid having
// the build fail if buildtime_bindgen is on, our bindings have
// `sqlite3_module::xShadowName`, but vtab_v3 wasn't specified.
fn zeroed_module() -> ffi::sqlite3_module {
// This is safe, as bindgen-generated structs are allowed to be zeroed.
unsafe { std::mem::MaybeUninit::zeroed().assume_init() }
}
/// Create a read-only virtual table implementation. /// Create a read-only virtual table implementation.
/// ///
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations). /// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
@ -100,8 +108,7 @@ pub fn read_only_module<T: CreateVTab>(version: c_int) -> Module<T> {
xSavepoint: None, xSavepoint: None,
xRelease: None, xRelease: None,
xRollbackTo: None, xRollbackTo: None,
#[cfg(any(feature = "bundled", feature = "vtab_v3"))] .. zeroed_module()
xShadowName: None,
}; };
Module { Module {
base: ffi_module, base: ffi_module,
@ -140,8 +147,7 @@ pub fn eponymous_only_module<T: VTab>(version: c_int) -> Module<T> {
xSavepoint: None, xSavepoint: None,
xRelease: None, xRelease: None,
xRollbackTo: None, xRollbackTo: None,
#[cfg(any(feature = "bundled", feature = "vtab_v3"))] .. zeroed_module()
xShadowName: None,
}; };
Module { Module {
base: ffi_module, base: ffi_module,
@ -309,8 +315,8 @@ impl IndexInfo {
} }
} }
/// Estimated number of rows returned /// Estimated number of rows returned.
#[cfg(feature = "bundled")] // SQLite >= 3.8.2 #[cfg(feature = "modern_sqlite")] // SQLite >= 3.8.2
pub fn set_estimated_rows(&mut self, estimated_rows: i64) { pub fn set_estimated_rows(&mut self, estimated_rows: i64) {
unsafe { unsafe {
(*self.0).estimatedRows = estimated_rows; (*self.0).estimatedRows = estimated_rows;