mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-26 11:31:37 +08:00
commit
d6780ece27
@ -8,14 +8,14 @@ use std::path::Path;
|
|||||||
/// targetting, and this test must be made at run-time (of the build script) See
|
/// targetting, and this test must be made at run-time (of the build script) See
|
||||||
/// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
|
/// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
|
||||||
fn win_target() -> bool {
|
fn win_target() -> bool {
|
||||||
std::env::var("CARGO_CFG_WINDOWS").is_ok()
|
env::var("CARGO_CFG_WINDOWS").is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tells whether we're building for Android.
|
/// Tells whether we're building for Android.
|
||||||
/// See [`win_target`]
|
/// See [`win_target`]
|
||||||
#[cfg(any(feature = "bundled", feature = "bundled-windows"))]
|
#[cfg(any(feature = "bundled", feature = "bundled-windows"))]
|
||||||
fn android_target() -> bool {
|
fn android_target() -> bool {
|
||||||
std::env::var("CARGO_CFG_TARGET_OS").map_or(false, |v| v == "android")
|
env::var("CARGO_CFG_TARGET_OS").map_or(false, |v| v == "android")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tells whether a given compiler will be used `compiler_name` is compared to
|
/// Tells whether a given compiler will be used `compiler_name` is compared to
|
||||||
@ -23,7 +23,7 @@ fn android_target() -> bool {
|
|||||||
///
|
///
|
||||||
/// See [`win_target`]
|
/// See [`win_target`]
|
||||||
fn is_compiler(compiler_name: &str) -> bool {
|
fn is_compiler(compiler_name: &str) -> bool {
|
||||||
std::env::var("CARGO_CFG_TARGET_ENV").map_or(false, |v| v == compiler_name)
|
env::var("CARGO_CFG_TARGET_ENV").map_or(false, |v| v == compiler_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -178,7 +178,7 @@ mod build_bundled {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if cfg!(feature = "bundled-sqlcipher-vendored-openssl") {
|
if cfg!(feature = "bundled-sqlcipher-vendored-openssl") {
|
||||||
cfg.include(std::env::var("DEP_OPENSSL_INCLUDE").unwrap());
|
cfg.include(env::var("DEP_OPENSSL_INCLUDE").unwrap());
|
||||||
// cargo will resolve downstream to the static lib in
|
// cargo will resolve downstream to the static lib in
|
||||||
// openssl-sys
|
// openssl-sys
|
||||||
} else if is_windows {
|
} else if is_windows {
|
||||||
@ -505,7 +505,7 @@ mod bindings {
|
|||||||
|
|
||||||
impl ParseCallbacks for SqliteTypeChooser {
|
impl ParseCallbacks for SqliteTypeChooser {
|
||||||
fn int_macro(&self, _name: &str, value: i64) -> Option<IntKind> {
|
fn int_macro(&self, _name: &str, value: i64) -> Option<IntKind> {
|
||||||
if value >= i32::min_value() as i64 && value <= i32::max_value() as i64 {
|
if value >= i32::MIN as i64 && value <= i32::MAX as i64 {
|
||||||
Some(IntKind::I32)
|
Some(IntKind::I32)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -43,7 +43,7 @@ pub(super) unsafe fn set_result(ctx: *mut sqlite3_context, result: &ToSqlOutput<
|
|||||||
ValueRef::Real(r) => ffi::sqlite3_result_double(ctx, r),
|
ValueRef::Real(r) => ffi::sqlite3_result_double(ctx, r),
|
||||||
ValueRef::Text(s) => {
|
ValueRef::Text(s) => {
|
||||||
let length = s.len();
|
let length = s.len();
|
||||||
if length > c_int::max_value() as usize {
|
if length > c_int::MAX as usize {
|
||||||
ffi::sqlite3_result_error_toobig(ctx);
|
ffi::sqlite3_result_error_toobig(ctx);
|
||||||
} else {
|
} else {
|
||||||
let (c_str, len, destructor) = match str_for_sqlite(s) {
|
let (c_str, len, destructor) = match str_for_sqlite(s) {
|
||||||
@ -57,7 +57,7 @@ pub(super) unsafe fn set_result(ctx: *mut sqlite3_context, result: &ToSqlOutput<
|
|||||||
}
|
}
|
||||||
ValueRef::Blob(b) => {
|
ValueRef::Blob(b) => {
|
||||||
let length = b.len();
|
let length = b.len();
|
||||||
if length > c_int::max_value() as usize {
|
if length > c_int::MAX as usize {
|
||||||
ffi::sqlite3_result_error_toobig(ctx);
|
ffi::sqlite3_result_error_toobig(ctx);
|
||||||
} else if length == 0 {
|
} else if length == 0 {
|
||||||
ffi::sqlite3_result_zeroblob(ctx, 0);
|
ffi::sqlite3_result_zeroblob(ctx, 0);
|
||||||
|
10
src/error.rs
10
src/error.rs
@ -34,7 +34,7 @@ pub enum Error {
|
|||||||
|
|
||||||
/// Error converting a string to a C-compatible string because it contained
|
/// Error converting a string to a C-compatible string because it contained
|
||||||
/// an embedded nul.
|
/// an embedded nul.
|
||||||
NulError(::std::ffi::NulError),
|
NulError(std::ffi::NulError),
|
||||||
|
|
||||||
/// Error when using SQL named parameters and passing a parameter name not
|
/// Error when using SQL named parameters and passing a parameter name not
|
||||||
/// present in the SQL.
|
/// present in the SQL.
|
||||||
@ -212,14 +212,14 @@ impl From<str::Utf8Error> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<::std::ffi::NulError> for Error {
|
impl From<std::ffi::NulError> for Error {
|
||||||
#[cold]
|
#[cold]
|
||||||
fn from(err: ::std::ffi::NulError) -> Error {
|
fn from(err: std::ffi::NulError) -> Error {
|
||||||
Error::NulError(err)
|
Error::NulError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const UNKNOWN_COLUMN: usize = std::usize::MAX;
|
const UNKNOWN_COLUMN: usize = usize::MAX;
|
||||||
|
|
||||||
/// The conversion isn't precise, but it's convenient to have it
|
/// The conversion isn't precise, but it's convenient to have it
|
||||||
/// to allow use of `get_raw(…).as_…()?` in callbacks that take `Error`.
|
/// to allow use of `get_raw(…).as_…()?` in callbacks that take `Error`.
|
||||||
@ -438,7 +438,7 @@ pub unsafe fn error_with_offset(db: *mut ffi::sqlite3, code: c_int, sql: &str) -
|
|||||||
|
|
||||||
pub fn check(code: c_int) -> Result<()> {
|
pub fn check(code: c_int) -> Result<()> {
|
||||||
if code != crate::ffi::SQLITE_OK {
|
if code != crate::ffi::SQLITE_OK {
|
||||||
Err(crate::error::error_from_sqlite_code(code, None))
|
Err(error_from_sqlite_code(code, None))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -637,7 +637,7 @@ unsafe extern "C" fn call_boxed_step<A, D, T>(
|
|||||||
D: Aggregate<A, T>,
|
D: Aggregate<A, T>,
|
||||||
T: ToSql,
|
T: ToSql,
|
||||||
{
|
{
|
||||||
let pac = if let Some(pac) = aggregate_context(ctx, ::std::mem::size_of::<*mut A>()) {
|
let pac = if let Some(pac) = aggregate_context(ctx, std::mem::size_of::<*mut A>()) {
|
||||||
pac
|
pac
|
||||||
} else {
|
} else {
|
||||||
ffi::sqlite3_result_error_nomem(ctx);
|
ffi::sqlite3_result_error_nomem(ctx);
|
||||||
@ -684,7 +684,7 @@ unsafe extern "C" fn call_boxed_inverse<A, W, T>(
|
|||||||
W: WindowAggregate<A, T>,
|
W: WindowAggregate<A, T>,
|
||||||
T: ToSql,
|
T: ToSql,
|
||||||
{
|
{
|
||||||
let pac = if let Some(pac) = aggregate_context(ctx, ::std::mem::size_of::<*mut A>()) {
|
let pac = if let Some(pac) = aggregate_context(ctx, std::mem::size_of::<*mut A>()) {
|
||||||
pac
|
pac
|
||||||
} else {
|
} else {
|
||||||
ffi::sqlite3_result_error_nomem(ctx);
|
ffi::sqlite3_result_error_nomem(ctx);
|
||||||
@ -807,7 +807,6 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::f64::EPSILON;
|
|
||||||
use std::os::raw::c_double;
|
use std::os::raw::c_double;
|
||||||
|
|
||||||
#[cfg(feature = "window")]
|
#[cfg(feature = "window")]
|
||||||
@ -832,7 +831,7 @@ mod test {
|
|||||||
)?;
|
)?;
|
||||||
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
||||||
|
|
||||||
assert!((3f64 - result?).abs() < EPSILON);
|
assert!((3f64 - result?).abs() < f64::EPSILON);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,7 +845,7 @@ mod test {
|
|||||||
half,
|
half,
|
||||||
)?;
|
)?;
|
||||||
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
||||||
assert!((3f64 - result?).abs() < EPSILON);
|
assert!((3f64 - result?).abs() < f64::EPSILON);
|
||||||
|
|
||||||
db.remove_function("half", 1)?;
|
db.remove_function("half", 1)?;
|
||||||
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
||||||
|
@ -37,7 +37,7 @@ impl From<i32> for Action {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The context recieved by an authorizer hook.
|
/// The context received by an authorizer hook.
|
||||||
///
|
///
|
||||||
/// See <https://sqlite.org/c3ref/set_authorizer.html> for more info.
|
/// See <https://sqlite.org/c3ref/set_authorizer.html> for more info.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
@ -25,11 +25,11 @@ pub struct InnerConnection {
|
|||||||
// interrupt would only acquire the lock after the query's completion.
|
// interrupt would only acquire the lock after the query's completion.
|
||||||
interrupt_lock: Arc<Mutex<*mut ffi::sqlite3>>,
|
interrupt_lock: Arc<Mutex<*mut ffi::sqlite3>>,
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
pub free_commit_hook: Option<unsafe fn(*mut ::std::os::raw::c_void)>,
|
pub free_commit_hook: Option<unsafe fn(*mut std::os::raw::c_void)>,
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
pub free_rollback_hook: Option<unsafe fn(*mut ::std::os::raw::c_void)>,
|
pub free_rollback_hook: Option<unsafe fn(*mut std::os::raw::c_void)>,
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
pub free_update_hook: Option<unsafe fn(*mut ::std::os::raw::c_void)>,
|
pub free_update_hook: Option<unsafe fn(*mut std::os::raw::c_void)>,
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
pub progress_handler: Option<Box<dyn FnMut() -> bool + Send>>,
|
pub progress_handler: Option<Box<dyn FnMut() -> bool + Send>>,
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
@ -208,7 +208,7 @@ impl InnerConnection {
|
|||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
let message = super::errmsg_to_string(errmsg);
|
let message = super::errmsg_to_string(errmsg);
|
||||||
ffi::sqlite3_free(errmsg.cast::<::std::os::raw::c_void>());
|
ffi::sqlite3_free(errmsg.cast::<std::os::raw::c_void>());
|
||||||
Err(error_from_sqlite_code(r, Some(message)))
|
Err(error_from_sqlite_code(r, Some(message)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -400,7 +400,7 @@ fn ensure_safe_sqlite_threading_mode() -> Result<()> {
|
|||||||
|
|
||||||
#[cfg(not(any(target_arch = "wasm32")))]
|
#[cfg(not(any(target_arch = "wasm32")))]
|
||||||
fn ensure_safe_sqlite_threading_mode() -> Result<()> {
|
fn ensure_safe_sqlite_threading_mode() -> Result<()> {
|
||||||
// Ensure SQLite was compiled in thredsafe mode.
|
// Ensure SQLite was compiled in threadsafe mode.
|
||||||
if unsafe { ffi::sqlite3_threadsafe() == 0 } {
|
if unsafe { ffi::sqlite3_threadsafe() == 0 } {
|
||||||
return Err(Error::SqliteSingleThreadedMode);
|
return Err(Error::SqliteSingleThreadedMode);
|
||||||
}
|
}
|
||||||
|
16
src/lib.rs
16
src/lib.rs
@ -57,7 +57,6 @@
|
|||||||
pub use libsqlite3_sys as ffi;
|
pub use libsqlite3_sys as ffi;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::convert;
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -272,7 +271,7 @@ fn str_for_sqlite(s: &[u8]) -> Result<(*const c_char, c_int, ffi::sqlite3_destru
|
|||||||
// Helper to cast to c_int safely, returning the correct error type if the cast
|
// Helper to cast to c_int safely, returning the correct error type if the cast
|
||||||
// failed.
|
// failed.
|
||||||
fn len_as_c_int(len: usize) -> Result<c_int> {
|
fn len_as_c_int(len: usize) -> Result<c_int> {
|
||||||
if len >= (c_int::max_value() as usize) {
|
if len >= (c_int::MAX as usize) {
|
||||||
Err(Error::SqliteFailure(
|
Err(Error::SqliteFailure(
|
||||||
ffi::Error::new(ffi::SQLITE_TOOBIG),
|
ffi::Error::new(ffi::SQLITE_TOOBIG),
|
||||||
None,
|
None,
|
||||||
@ -323,7 +322,7 @@ pub const TEMP_DB: DatabaseName<'static> = DatabaseName::Temp;
|
|||||||
))]
|
))]
|
||||||
impl DatabaseName<'_> {
|
impl DatabaseName<'_> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_cstring(&self) -> Result<util::SmallCString> {
|
fn as_cstring(&self) -> Result<SmallCString> {
|
||||||
use self::DatabaseName::{Attached, Main, Temp};
|
use self::DatabaseName::{Attached, Main, Temp};
|
||||||
match *self {
|
match *self {
|
||||||
Main => str_to_cstring("main"),
|
Main => str_to_cstring("main"),
|
||||||
@ -724,7 +723,7 @@ impl Connection {
|
|||||||
where
|
where
|
||||||
P: Params,
|
P: Params,
|
||||||
F: FnOnce(&Row<'_>) -> Result<T, E>,
|
F: FnOnce(&Row<'_>) -> Result<T, E>,
|
||||||
E: convert::From<Error>,
|
E: From<Error>,
|
||||||
{
|
{
|
||||||
let mut stmt = self.prepare(sql)?;
|
let mut stmt = self.prepare(sql)?;
|
||||||
stmt.check_no_tail()?;
|
stmt.check_no_tail()?;
|
||||||
@ -1434,8 +1433,9 @@ mod test {
|
|||||||
fn test_execute_select() {
|
fn test_execute_select() {
|
||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
let err = db.execute("SELECT 1 WHERE 1 < ?", [1i32]).unwrap_err();
|
let err = db.execute("SELECT 1 WHERE 1 < ?", [1i32]).unwrap_err();
|
||||||
assert!(
|
assert_eq!(
|
||||||
err == Error::ExecuteReturnedResults,
|
err,
|
||||||
|
Error::ExecuteReturnedResults,
|
||||||
"Unexpected error: {}",
|
"Unexpected error: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
@ -1739,7 +1739,7 @@ mod test {
|
|||||||
db.create_scalar_function(
|
db.create_scalar_function(
|
||||||
"interrupt",
|
"interrupt",
|
||||||
0,
|
0,
|
||||||
crate::functions::FunctionFlags::default(),
|
functions::FunctionFlags::default(),
|
||||||
move |_| {
|
move |_| {
|
||||||
interrupt_handle.interrupt();
|
interrupt_handle.interrupt();
|
||||||
Ok(0)
|
Ok(0)
|
||||||
@ -2121,7 +2121,7 @@ mod test {
|
|||||||
#[cfg(feature = "modern_sqlite")]
|
#[cfg(feature = "modern_sqlite")]
|
||||||
pub fn db_readonly() -> Result<()> {
|
pub fn db_readonly() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
assert!(!db.is_readonly(super::MAIN_DB)?);
|
assert!(!db.is_readonly(MAIN_DB)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ use sealed::Sealed;
|
|||||||
/// - Using the [`rusqlite::params!`](crate::params!) macro, e.g.
|
/// - Using the [`rusqlite::params!`](crate::params!) macro, e.g.
|
||||||
/// `thing.query(rusqlite::params![1, "foo", bar])`. This is mostly useful for
|
/// `thing.query(rusqlite::params![1, "foo", bar])`. This is mostly useful for
|
||||||
/// heterogeneous lists where the number of parameters greater than 16, or
|
/// heterogeneous lists where the number of parameters greater than 16, or
|
||||||
/// homogenous lists of paramters where the number of parameters exceeds 32.
|
/// homogenous lists of parameters where the number of parameters exceeds 32.
|
||||||
///
|
///
|
||||||
/// - For small homogeneous lists of parameters, they can either be passed as:
|
/// - For small homogeneous lists of parameters, they can either be passed as:
|
||||||
///
|
///
|
||||||
|
@ -110,7 +110,7 @@ impl RawStatement {
|
|||||||
#[cfg(feature = "unlock_notify")]
|
#[cfg(feature = "unlock_notify")]
|
||||||
pub fn step(&self) -> c_int {
|
pub fn step(&self) -> c_int {
|
||||||
use crate::unlock_notify;
|
use crate::unlock_notify;
|
||||||
let mut db = core::ptr::null_mut::<ffi::sqlite3>();
|
let mut db = ptr::null_mut::<ffi::sqlite3>();
|
||||||
loop {
|
loop {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut rc = ffi::sqlite3_step(self.ptr);
|
let mut rc = ffi::sqlite3_step(self.ptr);
|
||||||
|
@ -171,7 +171,7 @@ pub struct AndThenRows<'stmt, F> {
|
|||||||
|
|
||||||
impl<T, E, F> Iterator for AndThenRows<'_, F>
|
impl<T, E, F> Iterator for AndThenRows<'_, F>
|
||||||
where
|
where
|
||||||
E: convert::From<Error>,
|
E: From<Error>,
|
||||||
F: FnMut(&Row<'_>) -> Result<T, E>,
|
F: FnMut(&Row<'_>) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
type Item = Result<T, E>;
|
type Item = Result<T, E>;
|
||||||
|
@ -168,7 +168,7 @@ impl Session<'_> {
|
|||||||
if r != ffi::SQLITE_OK {
|
if r != ffi::SQLITE_OK {
|
||||||
let errmsg: *mut c_char = errmsg;
|
let errmsg: *mut c_char = errmsg;
|
||||||
let message = errmsg_to_string(&*errmsg);
|
let message = errmsg_to_string(&*errmsg);
|
||||||
ffi::sqlite3_free(errmsg as *mut ::std::os::raw::c_void);
|
ffi::sqlite3_free(errmsg as *mut c_void);
|
||||||
return Err(error_from_sqlite_code(r, Some(message)));
|
return Err(error_from_sqlite_code(r, Some(message)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use std::os::raw::{c_int, c_void};
|
|||||||
#[cfg(feature = "array")]
|
#[cfg(feature = "array")]
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::slice::from_raw_parts;
|
use std::slice::from_raw_parts;
|
||||||
use std::{convert, fmt, mem, ptr, str};
|
use std::{fmt, mem, ptr, str};
|
||||||
|
|
||||||
use super::ffi;
|
use super::ffi;
|
||||||
use super::{len_as_c_int, str_for_sqlite};
|
use super::{len_as_c_int, str_for_sqlite};
|
||||||
@ -417,7 +417,7 @@ impl Statement<'_> {
|
|||||||
pub fn query_and_then<T, E, P, F>(&mut self, params: P, f: F) -> Result<AndThenRows<'_, F>>
|
pub fn query_and_then<T, E, P, F>(&mut self, params: P, f: F) -> Result<AndThenRows<'_, F>>
|
||||||
where
|
where
|
||||||
P: Params,
|
P: Params,
|
||||||
E: convert::From<Error>,
|
E: From<Error>,
|
||||||
F: FnMut(&Row<'_>) -> Result<T, E>,
|
F: FnMut(&Row<'_>) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
self.query(params).map(|rows| rows.and_then(f))
|
self.query(params).map(|rows| rows.and_then(f))
|
||||||
@ -447,7 +447,7 @@ impl Statement<'_> {
|
|||||||
f: F,
|
f: F,
|
||||||
) -> Result<AndThenRows<'_, F>>
|
) -> Result<AndThenRows<'_, F>>
|
||||||
where
|
where
|
||||||
E: convert::From<Error>,
|
E: From<Error>,
|
||||||
F: FnMut(&Row<'_>) -> Result<T, E>,
|
F: FnMut(&Row<'_>) -> Result<T, E>,
|
||||||
{
|
{
|
||||||
self.query_and_then(params, f)
|
self.query_and_then(params, f)
|
||||||
|
@ -559,7 +559,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn assert_nested_tx_error(e: crate::Error) {
|
fn assert_nested_tx_error(e: Error) {
|
||||||
if let Error::SqliteFailure(e, Some(m)) = &e {
|
if let Error::SqliteFailure(e, Some(m)) = &e {
|
||||||
assert_eq!(e.extended_code, crate::ffi::SQLITE_ERROR);
|
assert_eq!(e.extended_code, crate::ffi::SQLITE_ERROR);
|
||||||
// FIXME: Not ideal...
|
// FIXME: Not ideal...
|
||||||
|
@ -240,7 +240,7 @@ mod test {
|
|||||||
|
|
||||||
fn check_ranges<T>(db: &Connection, out_of_range: &[i64], in_range: &[i64])
|
fn check_ranges<T>(db: &Connection, out_of_range: &[i64], in_range: &[i64])
|
||||||
where
|
where
|
||||||
T: Into<i64> + FromSql + ::std::fmt::Debug,
|
T: Into<i64> + FromSql + std::fmt::Debug,
|
||||||
{
|
{
|
||||||
for n in out_of_range {
|
for n in out_of_range {
|
||||||
let err = db
|
let err = db
|
||||||
|
@ -140,7 +140,6 @@ impl fmt::Display for Type {
|
|||||||
mod test {
|
mod test {
|
||||||
use super::Value;
|
use super::Value;
|
||||||
use crate::{params, Connection, Error, Result, Statement};
|
use crate::{params, Connection, Error, Result, Statement};
|
||||||
use std::f64::EPSILON;
|
|
||||||
use std::os::raw::{c_double, c_int};
|
use std::os::raw::{c_double, c_int};
|
||||||
|
|
||||||
fn checked_memory_handle() -> Result<Connection> {
|
fn checked_memory_handle() -> Result<Connection> {
|
||||||
@ -264,7 +263,7 @@ mod test {
|
|||||||
assert_eq!(vec![1, 2], row.get::<_, Vec<u8>>(0)?);
|
assert_eq!(vec![1, 2], row.get::<_, Vec<u8>>(0)?);
|
||||||
assert_eq!("text", row.get::<_, String>(1)?);
|
assert_eq!("text", row.get::<_, String>(1)?);
|
||||||
assert_eq!(1, row.get::<_, c_int>(2)?);
|
assert_eq!(1, row.get::<_, c_int>(2)?);
|
||||||
assert!((1.5 - row.get::<_, c_double>(3)?).abs() < EPSILON);
|
assert!((1.5 - row.get::<_, c_double>(3)?).abs() < f64::EPSILON);
|
||||||
assert_eq!(row.get::<_, Option<c_int>>(4)?, None);
|
assert_eq!(row.get::<_, Option<c_int>>(4)?, None);
|
||||||
assert_eq!(row.get::<_, Option<c_double>>(4)?, None);
|
assert_eq!(row.get::<_, Option<c_double>>(4)?, None);
|
||||||
assert_eq!(row.get::<_, Option<String>>(4)?, None);
|
assert_eq!(row.get::<_, Option<String>>(4)?, None);
|
||||||
@ -355,7 +354,7 @@ mod test {
|
|||||||
assert_eq!(Value::Text(String::from("text")), row.get::<_, Value>(1)?);
|
assert_eq!(Value::Text(String::from("text")), row.get::<_, Value>(1)?);
|
||||||
assert_eq!(Value::Integer(1), row.get::<_, Value>(2)?);
|
assert_eq!(Value::Integer(1), row.get::<_, Value>(2)?);
|
||||||
match row.get::<_, Value>(3)? {
|
match row.get::<_, Value>(3)? {
|
||||||
Value::Real(val) => assert!((1.5 - val).abs() < EPSILON),
|
Value::Real(val) => assert!((1.5 - val).abs() < f64::EPSILON),
|
||||||
x => panic!("Invalid Value {:?}", x),
|
x => panic!("Invalid Value {:?}", x),
|
||||||
}
|
}
|
||||||
assert_eq!(Value::Null, row.get::<_, Value>(4)?);
|
assert_eq!(Value::Null, row.get::<_, Value>(4)?);
|
||||||
|
@ -363,7 +363,6 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_i128() -> crate::Result<()> {
|
fn test_i128() -> crate::Result<()> {
|
||||||
use crate::Connection;
|
use crate::Connection;
|
||||||
use std::i128;
|
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo (i128 BLOB, desc TEXT)")?;
|
db.execute_batch("CREATE TABLE foo (i128 BLOB, desc TEXT)")?;
|
||||||
db.execute(
|
db.execute(
|
||||||
|
@ -5,7 +5,7 @@ use std::ffi::{CStr, CString, NulError};
|
|||||||
/// small enough. Also guarantees it's input is UTF-8 -- used for cases where we
|
/// small enough. Also guarantees it's input is UTF-8 -- used for cases where we
|
||||||
/// need to pass a NUL-terminated string to SQLite, and we have a `&str`.
|
/// need to pass a NUL-terminated string to SQLite, and we have a `&str`.
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub(crate) struct SmallCString(smallvec::SmallVec<[u8; 16]>);
|
pub(crate) struct SmallCString(SmallVec<[u8; 16]>);
|
||||||
|
|
||||||
impl SmallCString {
|
impl SmallCString {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//! // Note: This should be done once (usually when opening the DB).
|
//! // Note: This should be done once (usually when opening the DB).
|
||||||
//! let db = Connection::open_in_memory()?;
|
//! let db = Connection::open_in_memory()?;
|
||||||
//! rusqlite::vtab::csvtab::load_module(&db)?;
|
//! rusqlite::vtab::csvtab::load_module(&db)?;
|
||||||
//! // Assum3e my_csv.csv
|
//! // Assume my_csv.csv
|
||||||
//! let schema = "
|
//! let schema = "
|
||||||
//! CREATE VIRTUAL TABLE my_csv_data
|
//! CREATE VIRTUAL TABLE my_csv_data
|
||||||
//! USING csv(filename = 'my_csv.csv')
|
//! USING csv(filename = 'my_csv.csv')
|
||||||
|
@ -963,7 +963,7 @@ where
|
|||||||
.map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
|
.map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
match T::create(&mut conn, aux.as_ref(), &vec[..]) {
|
match T::create(&mut conn, aux.as_ref(), &vec[..]) {
|
||||||
Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
|
Ok((sql, vtab)) => match std::ffi::CString::new(sql) {
|
||||||
Ok(c_sql) => {
|
Ok(c_sql) => {
|
||||||
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
|
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
|
||||||
if rc == ffi::SQLITE_OK {
|
if rc == ffi::SQLITE_OK {
|
||||||
@ -1015,7 +1015,7 @@ where
|
|||||||
.map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
|
.map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
match T::connect(&mut conn, aux.as_ref(), &vec[..]) {
|
match T::connect(&mut conn, aux.as_ref(), &vec[..]) {
|
||||||
Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
|
Ok((sql, vtab)) => match std::ffi::CString::new(sql) {
|
||||||
Ok(c_sql) => {
|
Ok(c_sql) => {
|
||||||
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
|
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
|
||||||
if rc == ffi::SQLITE_OK {
|
if rc == ffi::SQLITE_OK {
|
||||||
|
Loading…
Reference in New Issue
Block a user