Merge pull request #473 from gwenn/misc

Misc
This commit is contained in:
gwenn 2019-02-02 12:44:50 +01:00 committed by GitHub
commit 08e51e69cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 84 additions and 76 deletions

View File

@ -19,6 +19,9 @@ maintenance = { status = "actively-developed" }
[lib]
name = "rusqlite"
[workspace]
members = ["libsqlite3-sys"]
[features]
load_extension = []
# hot-backup interface: 3.6.11 (2009-02-18)

View File

@ -115,9 +115,10 @@ impl error::Error for Error {
}
// Result codes.
// Note: These are not public because our bindgen bindings export whichever constants are present
// in the current version of SQLite. We repeat them here so we don't have to worry about which
// version of SQLite added which constants, and we only use them to implement code_to_str below.
// Note: These are not public because our bindgen bindings export whichever
// constants are present in the current version of SQLite. We repeat them here
// so we don't have to worry about which version of SQLite added which
// constants, and we only use them to implement code_to_str below.
const SQLITE_NOTICE: c_int = 27;
const SQLITE_WARNING: c_int = 28;

View File

@ -16,32 +16,36 @@ pub fn SQLITE_TRANSIENT() -> sqlite3_destructor_type {
}
/// Run-Time Limit Categories
#[repr(C)]
#[repr(i32)]
pub enum Limit {
/// The maximum size of any string or BLOB or table row, in bytes.
SQLITE_LIMIT_LENGTH = SQLITE_LIMIT_LENGTH as isize,
SQLITE_LIMIT_LENGTH = SQLITE_LIMIT_LENGTH,
/// The maximum length of an SQL statement, in bytes.
SQLITE_LIMIT_SQL_LENGTH = SQLITE_LIMIT_SQL_LENGTH as isize,
/// The maximum number of columns in a table definition or in the result set of a SELECT
/// or the maximum number of columns in an index or in an ORDER BY or GROUP BY clause.
SQLITE_LIMIT_COLUMN = SQLITE_LIMIT_COLUMN as isize,
SQLITE_LIMIT_SQL_LENGTH = SQLITE_LIMIT_SQL_LENGTH,
/// The maximum number of columns in a table definition or in the result set
/// of a SELECT or the maximum number of columns in an index or in an
/// ORDER BY or GROUP BY clause.
SQLITE_LIMIT_COLUMN = SQLITE_LIMIT_COLUMN,
/// The maximum depth of the parse tree on any expression.
SQLITE_LIMIT_EXPR_DEPTH = SQLITE_LIMIT_EXPR_DEPTH as isize,
SQLITE_LIMIT_EXPR_DEPTH = SQLITE_LIMIT_EXPR_DEPTH,
/// The maximum number of terms in a compound SELECT statement.
SQLITE_LIMIT_COMPOUND_SELECT = SQLITE_LIMIT_COMPOUND_SELECT as isize,
/// The maximum number of instructions in a virtual machine program used to implement an SQL statement.
SQLITE_LIMIT_VDBE_OP = SQLITE_LIMIT_VDBE_OP as isize,
SQLITE_LIMIT_COMPOUND_SELECT = SQLITE_LIMIT_COMPOUND_SELECT,
/// The maximum number of instructions in a virtual machine program used to
/// implement an SQL statement.
SQLITE_LIMIT_VDBE_OP = SQLITE_LIMIT_VDBE_OP,
/// The maximum number of arguments on a function.
SQLITE_LIMIT_FUNCTION_ARG = SQLITE_LIMIT_FUNCTION_ARG as isize,
SQLITE_LIMIT_FUNCTION_ARG = SQLITE_LIMIT_FUNCTION_ARG,
/// The maximum number of attached databases.
SQLITE_LIMIT_ATTACHED = SQLITE_LIMIT_ATTACHED as isize,
/// The maximum length of the pattern argument to the LIKE or GLOB operators.
SQLITE_LIMIT_LIKE_PATTERN_LENGTH = SQLITE_LIMIT_LIKE_PATTERN_LENGTH as isize,
SQLITE_LIMIT_ATTACHED = SQLITE_LIMIT_ATTACHED,
/// The maximum length of the pattern argument to the LIKE or GLOB
/// operators.
SQLITE_LIMIT_LIKE_PATTERN_LENGTH = SQLITE_LIMIT_LIKE_PATTERN_LENGTH,
/// The maximum index number of any parameter in an SQL statement.
SQLITE_LIMIT_VARIABLE_NUMBER = SQLITE_LIMIT_VARIABLE_NUMBER as isize,
SQLITE_LIMIT_VARIABLE_NUMBER = SQLITE_LIMIT_VARIABLE_NUMBER,
/// The maximum depth of recursion for triggers.
SQLITE_LIMIT_TRIGGER_DEPTH = 10,
/// The maximum number of auxiliary worker threads that a single prepared statement may start.
/// The maximum number of auxiliary worker threads that a single prepared
/// statement may start.
SQLITE_LIMIT_WORKER_THREADS = 11,
}

View File

@ -33,7 +33,7 @@ impl Connection {
///
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
/// or if the underlying SQLite call fails.
pub fn prepare_cached<'a>(&'a self, sql: &str) -> Result<CachedStatement<'a>> {
pub fn prepare_cached(&self, sql: &str) -> Result<CachedStatement<'_>> {
self.cache.get(self, sql)
}

View File

@ -12,7 +12,7 @@ use crate::types::{ToSqlOutput, ValueRef};
#[cfg(feature = "array")]
use crate::vtab::array::{free_array, ARRAY_TYPE};
pub(crate) unsafe fn set_result<'a>(ctx: *mut sqlite3_context, result: &ToSqlOutput<'a>) {
pub(crate) unsafe fn set_result(ctx: *mut sqlite3_context, result: &ToSqlOutput<'_>) {
let value = match *result {
ToSqlOutput::Borrowed(v) => v,
ToSqlOutput::Owned(ref v) => ValueRef::from(v),

View File

@ -523,7 +523,7 @@ mod test {
use crate::{Connection, Error, Result, NO_PARAMS};
fn half(ctx: &Context<'_>) -> Result<c_double> {
assert!(ctx.len() == 1, "called with unexpected number of arguments");
assert_eq!(ctx.len(), 1, "called with unexpected number of arguments");
let value = ctx.get::<c_double>(0)?;
Ok(value / 2f64)
}
@ -553,7 +553,7 @@ mod test {
// (https://www.sqlite.org/c3ref/get_auxdata.html) to avoid recompiling the regular
// expression multiple times within one query.
fn regexp_with_auxilliary(ctx: &Context<'_>) -> Result<bool> {
assert!(ctx.len() == 2, "called with unexpected number of arguments");
assert_eq!(ctx.len(), 2, "called with unexpected number of arguments");
let saved_re: Option<&Regex> = ctx.get_aux(0)?;
let new_re = match saved_re {
@ -634,7 +634,7 @@ mod test {
// until the function is removed.
let mut cached_regexes = HashMap::new();
db.create_scalar_function("regexp", 2, true, move |ctx| {
assert!(ctx.len() == 2, "called with unexpected number of arguments");
assert_eq!(ctx.len(), 2, "called with unexpected number of arguments");
let regex_s = ctx.get::<String>(0)?;
let entry = cached_regexes.entry(regex_s.clone());

View File

@ -11,11 +11,12 @@ use crate::{Connection, InnerConnection};
/// Action Codes
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(i32)]
pub enum Action {
UNKNOWN = -1,
SQLITE_DELETE = ffi::SQLITE_DELETE as isize,
SQLITE_INSERT = ffi::SQLITE_INSERT as isize,
SQLITE_UPDATE = ffi::SQLITE_UPDATE as isize,
SQLITE_DELETE = ffi::SQLITE_DELETE,
SQLITE_INSERT = ffi::SQLITE_INSERT,
SQLITE_UPDATE = ffi::SQLITE_UPDATE,
}
impl From<i32> for Action {
@ -242,15 +243,15 @@ mod test {
let db = Connection::open_in_memory().unwrap();
lazy_static! {
static ref called: AtomicBool = AtomicBool::new(false);
static ref CALLED: AtomicBool = AtomicBool::new(false);
}
db.commit_hook(Some(|| {
called.store(true, Ordering::Relaxed);
CALLED.store(true, Ordering::Relaxed);
false
}));
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); COMMIT;")
.unwrap();
assert!(called.load(Ordering::Relaxed));
assert!(CALLED.load(Ordering::Relaxed));
}
#[test]
@ -271,14 +272,14 @@ mod test {
let db = Connection::open_in_memory().unwrap();
lazy_static! {
static ref called: AtomicBool = AtomicBool::new(false);
static ref CALLED: AtomicBool = AtomicBool::new(false);
}
db.rollback_hook(Some(|| {
called.store(true, Ordering::Relaxed);
CALLED.store(true, Ordering::Relaxed);
}));
db.execute_batch("BEGIN; CREATE TABLE foo (t TEXT); ROLLBACK;")
.unwrap();
assert!(called.load(Ordering::Relaxed));
assert!(CALLED.load(Ordering::Relaxed));
}
#[test]
@ -286,17 +287,17 @@ mod test {
let db = Connection::open_in_memory().unwrap();
lazy_static! {
static ref called: AtomicBool = AtomicBool::new(false);
static ref CALLED: AtomicBool = AtomicBool::new(false);
}
db.update_hook(Some(|action, db: &str, tbl: &str, row_id| {
assert_eq!(Action::SQLITE_INSERT, action);
assert_eq!("main", db);
assert_eq!("foo", tbl);
assert_eq!(1, row_id);
called.store(true, Ordering::Relaxed);
CALLED.store(true, Ordering::Relaxed);
}));
db.execute_batch("CREATE TABLE foo (t TEXT)").unwrap();
db.execute_batch("INSERT INTO foo VALUES ('lisa')").unwrap();
assert!(called.load(Ordering::Relaxed));
assert!(CALLED.load(Ordering::Relaxed));
}
}

View File

@ -567,7 +567,7 @@ impl Connection {
///
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
/// or if the underlying SQLite call fails.
pub fn prepare<'a>(&'a self, sql: &str) -> Result<Statement<'a>> {
pub fn prepare(&self, sql: &str) -> Result<Statement<'_>> {
self.db.borrow_mut().prepare(self, sql)
}
@ -1247,11 +1247,9 @@ mod test {
let tx2 = db2.transaction().unwrap();
// SELECT first makes sqlite lock with a shared lock
let _ = tx1
.query_row("SELECT x FROM foo LIMIT 1", NO_PARAMS, |_| ())
tx1.query_row("SELECT x FROM foo LIMIT 1", NO_PARAMS, |_| ())
.unwrap();
let _ = tx2
.query_row("SELECT x FROM foo LIMIT 1", NO_PARAMS, |_| ())
tx2.query_row("SELECT x FROM foo LIMIT 1", NO_PARAMS, |_| ())
.unwrap();
tx1.execute("INSERT INTO foo VALUES(?1)", &[1]).unwrap();

View File

@ -57,13 +57,13 @@ mod test {
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() >= 3006018 {
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));
}
// SQLITE_LIMIT_WORKER_THREADS was added in SQLite 3.8.7.
if crate::version_number() >= 3008007 {
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));
}

View File

@ -258,7 +258,7 @@ impl Changeset {
}
/// Create an iterator to traverse a changeset
pub fn iter<'changeset>(&'changeset self) -> Result<ChangesetIter<'changeset>> {
pub fn iter(&self) -> Result<ChangesetIter<'_>> {
let mut it: *mut ffi::sqlite3_changeset_iter = unsafe { mem::uninitialized() };
check!(unsafe { ffi::sqlite3changeset_start(&mut it, self.n, self.cs) });
Ok(ChangesetIter {
@ -608,14 +608,15 @@ impl Connection {
}
/// Constants passed to the conflict handler
#[repr(i32)]
#[derive(Debug, PartialEq)]
pub enum ConflictType {
UNKNOWN = -1,
SQLITE_CHANGESET_DATA = ffi::SQLITE_CHANGESET_DATA as isize,
SQLITE_CHANGESET_NOTFOUND = ffi::SQLITE_CHANGESET_NOTFOUND as isize,
SQLITE_CHANGESET_CONFLICT = ffi::SQLITE_CHANGESET_CONFLICT as isize,
SQLITE_CHANGESET_CONSTRAINT = ffi::SQLITE_CHANGESET_CONSTRAINT as isize,
SQLITE_CHANGESET_FOREIGN_KEY = ffi::SQLITE_CHANGESET_FOREIGN_KEY as isize,
SQLITE_CHANGESET_DATA = ffi::SQLITE_CHANGESET_DATA,
SQLITE_CHANGESET_NOTFOUND = ffi::SQLITE_CHANGESET_NOTFOUND,
SQLITE_CHANGESET_CONFLICT = ffi::SQLITE_CHANGESET_CONFLICT,
SQLITE_CHANGESET_CONSTRAINT = ffi::SQLITE_CHANGESET_CONSTRAINT,
SQLITE_CHANGESET_FOREIGN_KEY = ffi::SQLITE_CHANGESET_FOREIGN_KEY,
}
impl From<i32> for ConflictType {
fn from(code: i32) -> ConflictType {
@ -631,11 +632,12 @@ impl From<i32> for ConflictType {
}
/// Constants returned by the conflict handler
#[repr(i32)]
#[derive(Debug, PartialEq)]
pub enum ConflictAction {
SQLITE_CHANGESET_OMIT = ffi::SQLITE_CHANGESET_OMIT as isize,
SQLITE_CHANGESET_REPLACE = ffi::SQLITE_CHANGESET_REPLACE as isize,
SQLITE_CHANGESET_ABORT = ffi::SQLITE_CHANGESET_ABORT as isize,
SQLITE_CHANGESET_OMIT = ffi::SQLITE_CHANGESET_OMIT,
SQLITE_CHANGESET_REPLACE = ffi::SQLITE_CHANGESET_REPLACE,
SQLITE_CHANGESET_ABORT = ffi::SQLITE_CHANGESET_ABORT,
}
unsafe extern "C" fn call_filter<F, C>(p_ctx: *mut c_void, tbl_str: *const c_char) -> c_int
@ -795,19 +797,19 @@ mod test {
.unwrap();
lazy_static! {
static ref called: AtomicBool = AtomicBool::new(false);
static ref CALLED: AtomicBool = AtomicBool::new(false);
}
db.apply(
&changeset,
None::<fn(&str) -> bool>,
|_conflict_type, _item| {
called.store(true, Ordering::Relaxed);
CALLED.store(true, Ordering::Relaxed);
ConflictAction::SQLITE_CHANGESET_OMIT
},
)
.unwrap();
assert!(!called.load(Ordering::Relaxed));
assert!(!CALLED.load(Ordering::Relaxed));
let check = db
.query_row("SELECT 1 FROM foo WHERE t = ?", &["bar"], |row| {
row.get::<_, i32>(0)
@ -820,7 +822,7 @@ mod test {
&changeset,
None::<fn(&str) -> bool>,
|conflict_type, item| {
called.store(true, Ordering::Relaxed);
CALLED.store(true, Ordering::Relaxed);
assert_eq!(ConflictType::SQLITE_CHANGESET_CONFLICT, conflict_type);
let conflict = item.conflict(0).unwrap();
assert_eq!(Ok("bar"), conflict.as_str());
@ -828,7 +830,7 @@ mod test {
},
)
.unwrap();
assert!(called.load(Ordering::Relaxed));
assert!(CALLED.load(Ordering::Relaxed));
}
#[test]

View File

@ -186,7 +186,7 @@ impl<'conn> Statement<'conn> {
/// ## Failure
///
/// Will return `Err` if binding parameters fails.
pub fn query<'a, P>(&'a mut self, params: P) -> Result<Rows<'a>>
pub fn query<P>(&mut self, params: P) -> Result<Rows<'_>>
where
P: IntoIterator,
P::Item: ToSql,
@ -263,7 +263,7 @@ impl<'conn> Statement<'conn> {
/// ## Failure
///
/// Will return `Err` if binding parameters fails.
pub fn query_map<'a, T, P, F>(&'a mut self, params: P, f: F) -> Result<MappedRows<'a, F>>
pub fn query_map<T, P, F>(&mut self, params: P, f: F) -> Result<MappedRows<'_, F>>
where
P: IntoIterator,
P::Item: ToSql,
@ -319,11 +319,7 @@ impl<'conn> Statement<'conn> {
/// # Failure
///
/// Will return `Err` if binding parameters fails.
pub fn query_and_then<'a, T, E, P, F>(
&'a mut self,
params: P,
f: F,
) -> Result<AndThenRows<'a, F>>
pub fn query_and_then<T, E, P, F>(&mut self, params: P, f: F) -> Result<AndThenRows<'_, F>>
where
P: IntoIterator,
P::Item: ToSql,
@ -858,6 +854,7 @@ mod test {
assert_eq!(1, doubled_id);
// second row should be Err
#[allow(clippy::match_wild_err_arm)]
match rows.next().unwrap() {
Ok(_) => panic!("invalid Ok"),
Err(Error::SqliteSingleThreadedMode) => (),
@ -1042,7 +1039,7 @@ mod test {
use std::collections::BTreeSet;
let data: BTreeSet<String> = ["one", "two", "three"]
.into_iter()
.iter()
.map(|s| s.to_string())
.collect();
db.query_row("SELECT ?1, ?2, ?3", &data, |row| row.get::<_, String>(0))

View File

@ -60,6 +60,7 @@ impl Error for FromSqlError {
}
#[allow(clippy::match_same_arms)]
#[allow(deprecated)]
fn cause(&self) -> Option<&dyn Error> {
match *self {
FromSqlError::Other(ref err) => err.cause(),
@ -231,11 +232,11 @@ mod test {
check_ranges::<i16>(&db, &[-32769, 32768], &[-32768, -1, 0, 1, 32767]);
check_ranges::<i32>(
&db,
&[-2147483649, 2147483648],
&[-2147483648, -1, 0, 1, 2147483647],
&[-2_147_483_649, 2_147_483_648],
&[-2_147_483_648, -1, 0, 1, 2_147_483_647],
);
check_ranges::<u8>(&db, &[-2, -1, 256], &[0, 1, 255]);
check_ranges::<u16>(&db, &[-2, -1, 65536], &[0, 1, 65535]);
check_ranges::<u32>(&db, &[-2, -1, 4294967296], &[0, 1, 4294967295]);
check_ranges::<u32>(&db, &[-2, -1, 4_294_967_296], &[0, 1, 4_294_967_295]);
}
}

View File

@ -223,6 +223,7 @@ mod test {
}
#[test]
#[allow(clippy::cyclomatic_complexity)]
fn test_mismatched_types() {
fn is_invalid_column_type(err: Error) -> bool {
match err {

View File

@ -54,10 +54,10 @@ mod test {
ts_vec.push(time::Timespec::new(10_000, 0)); //January 1, 1970 2:46:40 AM
ts_vec.push(time::Timespec::new(10_000, 1000)); //January 1, 1970 2:46:40 AM (and one microsecond)
ts_vec.push(time::Timespec::new(1500391124, 1_000_000)); //July 18, 2017
ts_vec.push(time::Timespec::new(2000000000, 2_000_000)); //May 18, 2033
ts_vec.push(time::Timespec::new(3000000000, 999_999_999)); //January 24, 2065
ts_vec.push(time::Timespec::new(10000000000, 0)); //November 20, 2286
ts_vec.push(time::Timespec::new(1_500_391_124, 1_000_000)); //July 18, 2017
ts_vec.push(time::Timespec::new(2_000_000_000, 2_000_000)); //May 18, 2033
ts_vec.push(time::Timespec::new(3_000_000_000, 999_999_999)); //January 24, 2065
ts_vec.push(time::Timespec::new(10_000_000_000, 0)); //November 20, 2286
for ts in ts_vec {
db.execute("INSERT INTO foo(t) VALUES (?)", &[&ts]).unwrap();

View File

@ -180,7 +180,7 @@ mod test {
array::load_module(&db).unwrap();
let v = vec![1i64, 2, 3, 4];
let values = v.into_iter().map(|i| Value::from(i)).collect();
let values = v.into_iter().map(Value::from).collect();
let ptr = Rc::new(values);
{
let mut stmt = db.prepare("SELECT value from rarray(?);").unwrap();

View File

@ -366,7 +366,7 @@ mod test {
.query_map(NO_PARAMS, |row| row.get::<_, i32>(0))
.unwrap()
.collect();
let sum = ids.unwrap().iter().fold(0, |acc, &id| acc + id);
let sum = ids.unwrap().iter().sum::<i32>();
assert_eq!(sum, 15);
}
db.execute_batch("DROP TABLE vtab").unwrap();

View File

@ -270,7 +270,7 @@ mod test {
#[test]
fn test_series_module() {
let version = unsafe { ffi::sqlite3_libversion_number() };
if version < 3008012 {
if version < 3_008_012 {
return;
}

View File

@ -88,7 +88,7 @@ fn test_dummy_module() {
.unwrap();
let version = version_number();
if version < 3008012 {
if version < 3_008_012 {
return;
}