mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-23 08:49:27 +08:00
commit
372291c65e
@ -10,9 +10,6 @@ Rusqlite is an ergonomic wrapper for using SQLite from Rust. It attempts to expo
|
|||||||
an interface similar to [rust-postgres](https://github.com/sfackler/rust-postgres).
|
an interface similar to [rust-postgres](https://github.com/sfackler/rust-postgres).
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
extern crate rusqlite;
|
|
||||||
extern crate time;
|
|
||||||
|
|
||||||
use rusqlite::types::ToSql;
|
use rusqlite::types::ToSql;
|
||||||
use rusqlite::{Connection, NO_PARAMS};
|
use rusqlite::{Connection, NO_PARAMS};
|
||||||
use time::Timespec;
|
use time::Timespec;
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
#![feature(extern_crate_item_prelude)]
|
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
extern crate rusqlite;
|
|
||||||
|
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ fn main() {
|
|||||||
|
|
||||||
#[cfg(feature = "bundled")]
|
#[cfg(feature = "bundled")]
|
||||||
mod build {
|
mod build {
|
||||||
extern crate cc;
|
use cc;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub fn main(out_dir: &str, out_path: &Path) {
|
pub fn main(out_dir: &str, out_path: &Path) {
|
||||||
@ -94,7 +94,7 @@ impl From<HeaderLocation> for String {
|
|||||||
|
|
||||||
#[cfg(not(feature = "bundled"))]
|
#[cfg(not(feature = "bundled"))]
|
||||||
mod build {
|
mod build {
|
||||||
extern crate pkg_config;
|
use pkg_config;
|
||||||
|
|
||||||
#[cfg(all(feature = "vcpkg", target_env = "msvc"))]
|
#[cfg(all(feature = "vcpkg", target_env = "msvc"))]
|
||||||
extern crate vcpkg;
|
extern crate vcpkg;
|
||||||
@ -201,7 +201,7 @@ mod bindings {
|
|||||||
|
|
||||||
#[cfg(feature = "buildtime_bindgen")]
|
#[cfg(feature = "buildtime_bindgen")]
|
||||||
mod bindings {
|
mod bindings {
|
||||||
extern crate bindgen;
|
use bindgen;
|
||||||
|
|
||||||
use self::bindgen::callbacks::{IntKind, ParseCallbacks};
|
use self::bindgen::callbacks::{IntKind, ParseCallbacks};
|
||||||
use super::HeaderLocation;
|
use super::HeaderLocation;
|
||||||
|
@ -98,7 +98,7 @@ impl Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Error code {}: {}",
|
"Error code {}: {}",
|
||||||
|
@ -57,7 +57,7 @@ impl Connection {
|
|||||||
/// or if the backup fails.
|
/// or if the backup fails.
|
||||||
pub fn backup<P: AsRef<Path>>(
|
pub fn backup<P: AsRef<Path>>(
|
||||||
&self,
|
&self,
|
||||||
name: DatabaseName,
|
name: DatabaseName<'_>,
|
||||||
dst_path: P,
|
dst_path: P,
|
||||||
progress: Option<fn(Progress)>,
|
progress: Option<fn(Progress)>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -95,7 +95,7 @@ impl Connection {
|
|||||||
/// or if the restore fails.
|
/// or if the restore fails.
|
||||||
pub fn restore<P: AsRef<Path>, F: Fn(Progress)>(
|
pub fn restore<P: AsRef<Path>, F: Fn(Progress)>(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: DatabaseName,
|
name: DatabaseName<'_>,
|
||||||
src_path: P,
|
src_path: P,
|
||||||
progress: Option<F>,
|
progress: Option<F>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@ -192,9 +192,9 @@ impl<'a, 'b> Backup<'a, 'b> {
|
|||||||
/// `NULL`.
|
/// `NULL`.
|
||||||
pub fn new_with_names(
|
pub fn new_with_names(
|
||||||
from: &'a Connection,
|
from: &'a Connection,
|
||||||
from_name: DatabaseName,
|
from_name: DatabaseName<'_>,
|
||||||
to: &'b mut Connection,
|
to: &'b mut Connection,
|
||||||
to_name: DatabaseName,
|
to_name: DatabaseName<'_>,
|
||||||
) -> Result<Backup<'a, 'b>> {
|
) -> Result<Backup<'a, 'b>> {
|
||||||
let to_name = to_name.to_cstring()?;
|
let to_name = to_name.to_cstring()?;
|
||||||
let from_name = from_name.to_cstring()?;
|
let from_name = from_name.to_cstring()?;
|
||||||
|
@ -84,7 +84,7 @@ impl Connection {
|
|||||||
/// fails.
|
/// fails.
|
||||||
pub fn blob_open<'a>(
|
pub fn blob_open<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
db: DatabaseName,
|
db: DatabaseName<'_>,
|
||||||
table: &str,
|
table: &str,
|
||||||
column: &str,
|
column: &str,
|
||||||
row_id: i64,
|
row_id: i64,
|
||||||
@ -254,7 +254,7 @@ impl<'conn> Drop for Blob<'conn> {
|
|||||||
pub struct ZeroBlob(pub i32);
|
pub struct ZeroBlob(pub i32);
|
||||||
|
|
||||||
impl ToSql for ZeroBlob {
|
impl ToSql for ZeroBlob {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
let ZeroBlob(length) = *self;
|
let ZeroBlob(length) = *self;
|
||||||
Ok(ToSqlOutput::ZeroBlob(length))
|
Ok(ToSqlOutput::ZeroBlob(length))
|
||||||
}
|
}
|
||||||
|
@ -74,12 +74,12 @@ impl InnerConnection {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
extern crate tempdir;
|
|
||||||
use self::tempdir::TempDir;
|
use self::tempdir::TempDir;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::mpsc::sync_channel;
|
use std::sync::mpsc::sync_channel;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use tempdir;
|
||||||
|
|
||||||
use crate::{Connection, Error, ErrorCode, TransactionBehavior, NO_PARAMS};
|
use crate::{Connection, Error, ErrorCode, TransactionBehavior, NO_PARAMS};
|
||||||
|
|
||||||
|
10
src/error.rs
10
src/error.rs
@ -19,7 +19,7 @@ pub enum Error {
|
|||||||
|
|
||||||
/// Error when the value of a particular column is requested, but it cannot
|
/// Error when the value of a particular column is requested, but it cannot
|
||||||
/// be converted to the requested Rust type.
|
/// be converted to the requested Rust type.
|
||||||
FromSqlConversionFailure(usize, Type, Box<error::Error + Send + Sync>),
|
FromSqlConversionFailure(usize, Type, Box<dyn error::Error + Send + Sync>),
|
||||||
|
|
||||||
/// Error when SQLite gives us an integral value outside the range of the
|
/// Error when SQLite gives us an integral value outside the range of the
|
||||||
/// requested type (e.g., trying to get the value 1000 into a `u8`).
|
/// requested type (e.g., trying to get the value 1000 into a `u8`).
|
||||||
@ -78,10 +78,10 @@ pub enum Error {
|
|||||||
/// `create_scalar_function`).
|
/// `create_scalar_function`).
|
||||||
#[cfg(feature = "functions")]
|
#[cfg(feature = "functions")]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
UserFunctionError(Box<error::Error + Send + Sync>),
|
UserFunctionError(Box<dyn error::Error + Send + Sync>),
|
||||||
|
|
||||||
/// Error available for the implementors of the `ToSql` trait.
|
/// Error available for the implementors of the `ToSql` trait.
|
||||||
ToSqlConversionFailure(Box<error::Error + Send + Sync>),
|
ToSqlConversionFailure(Box<dyn error::Error + Send + Sync>),
|
||||||
|
|
||||||
/// Error when the SQL is not a `SELECT`, is not read-only.
|
/// Error when the SQL is not a `SELECT`, is not read-only.
|
||||||
InvalidQuery,
|
InvalidQuery,
|
||||||
@ -106,7 +106,7 @@ impl From<::std::ffi::NulError> for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Error::SqliteFailure(ref err, None) => err.fmt(f),
|
Error::SqliteFailure(ref err, None) => err.fmt(f),
|
||||||
Error::SqliteFailure(_, Some(ref s)) => write!(f, "{}", s),
|
Error::SqliteFailure(_, Some(ref s)) => write!(f, "{}", s),
|
||||||
@ -191,7 +191,7 @@ impl error::Error for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&error::Error> {
|
fn cause(&self) -> Option<&dyn error::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
Error::SqliteFailure(ref err, _) => Some(err),
|
Error::SqliteFailure(ref err, _) => Some(err),
|
||||||
Error::Utf8Error(ref err) => Some(err),
|
Error::Utf8Error(ref err) => Some(err),
|
||||||
|
@ -198,7 +198,7 @@ where
|
|||||||
|
|
||||||
/// "step" function called once for each row in an aggregate group. May be
|
/// "step" function called once for each row in an aggregate group. May be
|
||||||
/// called 0 times if there are no rows.
|
/// called 0 times if there are no rows.
|
||||||
fn step(&self, _: &mut Context, _: &mut A) -> Result<()>;
|
fn step(&self, _: &mut Context<'_>, _: &mut A) -> Result<()>;
|
||||||
|
|
||||||
/// Computes and returns the final result. Will be called exactly once for
|
/// Computes and returns the final result. Will be called exactly once for
|
||||||
/// each invocation of the function. If `step()` was called at least
|
/// each invocation of the function. If `step()` was called at least
|
||||||
@ -246,7 +246,7 @@ impl Connection {
|
|||||||
x_func: F,
|
x_func: F,
|
||||||
) -> Result<()>
|
) -> Result<()>
|
||||||
where
|
where
|
||||||
F: FnMut(&Context) -> Result<T> + Send + 'static,
|
F: FnMut(&Context<'_>) -> Result<T> + Send + 'static,
|
||||||
T: ToSql,
|
T: ToSql,
|
||||||
{
|
{
|
||||||
self.db
|
self.db
|
||||||
@ -297,7 +297,7 @@ impl InnerConnection {
|
|||||||
x_func: F,
|
x_func: F,
|
||||||
) -> Result<()>
|
) -> Result<()>
|
||||||
where
|
where
|
||||||
F: FnMut(&Context) -> Result<T> + Send + 'static,
|
F: FnMut(&Context<'_>) -> Result<T> + Send + 'static,
|
||||||
T: ToSql,
|
T: ToSql,
|
||||||
{
|
{
|
||||||
unsafe extern "C" fn call_boxed_closure<F, T>(
|
unsafe extern "C" fn call_boxed_closure<F, T>(
|
||||||
@ -305,7 +305,7 @@ impl InnerConnection {
|
|||||||
argc: c_int,
|
argc: c_int,
|
||||||
argv: *mut *mut sqlite3_value,
|
argv: *mut *mut sqlite3_value,
|
||||||
) where
|
) where
|
||||||
F: FnMut(&Context) -> Result<T>,
|
F: FnMut(&Context<'_>) -> Result<T>,
|
||||||
T: ToSql,
|
T: ToSql,
|
||||||
{
|
{
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
@ -483,7 +483,7 @@ impl InnerConnection {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
extern crate regex;
|
use regex;
|
||||||
|
|
||||||
use self::regex::Regex;
|
use self::regex::Regex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -493,7 +493,7 @@ mod test {
|
|||||||
use crate::functions::{Aggregate, Context};
|
use crate::functions::{Aggregate, Context};
|
||||||
use crate::{Connection, Error, Result, NO_PARAMS};
|
use crate::{Connection, Error, Result, NO_PARAMS};
|
||||||
|
|
||||||
fn half(ctx: &Context) -> Result<c_double> {
|
fn half(ctx: &Context<'_>) -> Result<c_double> {
|
||||||
assert!(ctx.len() == 1, "called with unexpected number of arguments");
|
assert!(ctx.len() == 1, "called with unexpected number of arguments");
|
||||||
let value = ctx.get::<c_double>(0)?;
|
let value = ctx.get::<c_double>(0)?;
|
||||||
Ok(value / 2f64)
|
Ok(value / 2f64)
|
||||||
@ -523,7 +523,7 @@ mod test {
|
|||||||
// This implementation of a regexp scalar function uses SQLite's auxilliary data
|
// This implementation of a regexp scalar function uses SQLite's auxilliary data
|
||||||
// (https://www.sqlite.org/c3ref/get_auxdata.html) to avoid recompiling the regular
|
// (https://www.sqlite.org/c3ref/get_auxdata.html) to avoid recompiling the regular
|
||||||
// expression multiple times within one query.
|
// expression multiple times within one query.
|
||||||
fn regexp_with_auxilliary(ctx: &Context) -> Result<bool> {
|
fn regexp_with_auxilliary(ctx: &Context<'_>) -> Result<bool> {
|
||||||
assert!(ctx.len() == 2, "called with unexpected number of arguments");
|
assert!(ctx.len() == 2, "called with unexpected number of arguments");
|
||||||
|
|
||||||
let saved_re: Option<&Regex> = unsafe { ctx.get_aux(0) };
|
let saved_re: Option<&Regex> = unsafe { ctx.get_aux(0) };
|
||||||
@ -674,7 +674,7 @@ mod test {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(&self, ctx: &mut Context, sum: &mut i64) -> Result<()> {
|
fn step(&self, ctx: &mut Context<'_>, sum: &mut i64) -> Result<()> {
|
||||||
*sum += ctx.get::<i64>(0)?;
|
*sum += ctx.get::<i64>(0)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -689,7 +689,7 @@ mod test {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(&self, _ctx: &mut Context, sum: &mut i64) -> Result<()> {
|
fn step(&self, _ctx: &mut Context<'_>, sum: &mut i64) -> Result<()> {
|
||||||
*sum += 1;
|
*sum += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
33
src/lib.rs
33
src/lib.rs
@ -62,17 +62,14 @@
|
|||||||
//! ```
|
//! ```
|
||||||
#![allow(unknown_lints)]
|
#![allow(unknown_lints)]
|
||||||
|
|
||||||
extern crate libsqlite3_sys as ffi;
|
use libsqlite3_sys as ffi;
|
||||||
extern crate lru_cache;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
#[cfg(any(test, feature = "vtab"))]
|
#[cfg(any(test, feature = "vtab"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
#[cfg(feature = "i128_blob")]
|
|
||||||
extern crate byteorder;
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::convert;
|
use std::convert;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
@ -142,7 +139,7 @@ pub mod vtab;
|
|||||||
// Number of cached prepared statements we'll hold on to.
|
// Number of cached prepared statements we'll hold on to.
|
||||||
const STATEMENT_CACHE_DEFAULT_CAPACITY: usize = 16;
|
const STATEMENT_CACHE_DEFAULT_CAPACITY: usize = 16;
|
||||||
/// To be used when your statement has no [parameter](https://sqlite.org/lang_expr.html#varparam).
|
/// To be used when your statement has no [parameter](https://sqlite.org/lang_expr.html#varparam).
|
||||||
pub const NO_PARAMS: &[&ToSql] = &[];
|
pub const NO_PARAMS: &[&dyn ToSql] = &[];
|
||||||
|
|
||||||
/// A typedef of the result returned by many methods.
|
/// A typedef of the result returned by many methods.
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
@ -343,7 +340,7 @@ impl Connection {
|
|||||||
///
|
///
|
||||||
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
||||||
/// or if the underlying SQLite call fails.
|
/// or if the underlying SQLite call fails.
|
||||||
pub fn execute_named(&self, sql: &str, params: &[(&str, &ToSql)]) -> Result<usize> {
|
pub fn execute_named(&self, sql: &str, params: &[(&str, &dyn ToSql)]) -> Result<usize> {
|
||||||
self.prepare(sql)
|
self.prepare(sql)
|
||||||
.and_then(|mut stmt| stmt.execute_named(params))
|
.and_then(|mut stmt| stmt.execute_named(params))
|
||||||
}
|
}
|
||||||
@ -383,7 +380,7 @@ impl Connection {
|
|||||||
where
|
where
|
||||||
P: IntoIterator,
|
P: IntoIterator,
|
||||||
P::Item: ToSql,
|
P::Item: ToSql,
|
||||||
F: FnOnce(&Row) -> T,
|
F: FnOnce(&Row<'_, '_>) -> T,
|
||||||
{
|
{
|
||||||
let mut stmt = self.prepare(sql)?;
|
let mut stmt = self.prepare(sql)?;
|
||||||
stmt.query_row(params, f)
|
stmt.query_row(params, f)
|
||||||
@ -399,9 +396,9 @@ impl Connection {
|
|||||||
///
|
///
|
||||||
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
/// Will return `Err` if `sql` cannot be converted to a C-compatible string
|
||||||
/// or if the underlying SQLite call fails.
|
/// or if the underlying SQLite call fails.
|
||||||
pub fn query_row_named<T, F>(&self, sql: &str, params: &[(&str, &ToSql)], f: F) -> Result<T>
|
pub fn query_row_named<T, F>(&self, sql: &str, params: &[(&str, &dyn ToSql)], f: F) -> Result<T>
|
||||||
where
|
where
|
||||||
F: FnOnce(&Row) -> T,
|
F: FnOnce(&Row<'_, '_>) -> T,
|
||||||
{
|
{
|
||||||
let mut stmt = self.prepare(sql)?;
|
let mut stmt = self.prepare(sql)?;
|
||||||
let mut rows = stmt.query_named(params)?;
|
let mut rows = stmt.query_named(params)?;
|
||||||
@ -438,7 +435,7 @@ impl Connection {
|
|||||||
where
|
where
|
||||||
P: IntoIterator,
|
P: IntoIterator,
|
||||||
P::Item: ToSql,
|
P::Item: ToSql,
|
||||||
F: FnOnce(&Row) -> result::Result<T, E>,
|
F: FnOnce(&Row<'_, '_>) -> result::Result<T, E>,
|
||||||
E: convert::From<Error>,
|
E: convert::From<Error>,
|
||||||
{
|
{
|
||||||
let mut stmt = self.prepare(sql)?;
|
let mut stmt = self.prepare(sql)?;
|
||||||
@ -594,7 +591,7 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Connection {
|
impl fmt::Debug for Connection {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Connection")
|
f.debug_struct("Connection")
|
||||||
.field("path", &self.path)
|
.field("path", &self.path)
|
||||||
.finish()
|
.finish()
|
||||||
@ -1055,12 +1052,12 @@ impl Drop for InnerConnection {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
extern crate tempdir;
|
|
||||||
use self::tempdir::TempDir;
|
use self::tempdir::TempDir;
|
||||||
pub use super::*;
|
pub use super::*;
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
pub use std::error::Error as StdError;
|
pub use std::error::Error as StdError;
|
||||||
pub use std::fmt;
|
pub use std::fmt;
|
||||||
|
use tempdir;
|
||||||
|
|
||||||
// this function is never called, but is still type checked; in
|
// this function is never called, but is still type checked; in
|
||||||
// particular, calls with specific instantiations will require
|
// particular, calls with specific instantiations will require
|
||||||
@ -1548,7 +1545,9 @@ mod test {
|
|||||||
for (i, v) in vals.iter().enumerate() {
|
for (i, v) in vals.iter().enumerate() {
|
||||||
let i_to_insert = i as i64;
|
let i_to_insert = i as i64;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
insert_stmt.execute(&[&i_to_insert as &ToSql, &v]).unwrap(),
|
insert_stmt
|
||||||
|
.execute(&[&i_to_insert as &dyn ToSql, &v])
|
||||||
|
.unwrap(),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1566,7 +1565,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod query_and_then_tests {
|
mod query_and_then_tests {
|
||||||
extern crate libsqlite3_sys as ffi;
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -1576,7 +1575,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CustomError {
|
impl fmt::Display for CustomError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> ::std::result::Result<(), fmt::Error> {
|
||||||
match *self {
|
match *self {
|
||||||
CustomError::SomeError => write!(f, "{}", self.description()),
|
CustomError::SomeError => write!(f, "{}", self.description()),
|
||||||
CustomError::Sqlite(ref se) => write!(f, "{}: {}", self.description(), se),
|
CustomError::Sqlite(ref se) => write!(f, "{}: {}", self.description(), se),
|
||||||
@ -1589,7 +1588,7 @@ mod test {
|
|||||||
"my custom error"
|
"my custom error"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cause(&self) -> Option<&StdError> {
|
fn cause(&self) -> Option<&dyn StdError> {
|
||||||
match *self {
|
match *self {
|
||||||
CustomError::SomeError => None,
|
CustomError::SomeError => None,
|
||||||
CustomError::Sqlite(ref se) => Some(se),
|
CustomError::Sqlite(ref se) => Some(se),
|
||||||
|
@ -21,7 +21,7 @@ impl<'conn> LoadExtensionGuard<'conn> {
|
|||||||
/// Attempt to enable loading extensions. Loading extensions will be
|
/// Attempt to enable loading extensions. Loading extensions will be
|
||||||
/// disabled when this guard goes out of scope. Cannot be meaningfully
|
/// disabled when this guard goes out of scope. Cannot be meaningfully
|
||||||
/// nested.
|
/// nested.
|
||||||
pub fn new(conn: &Connection) -> Result<LoadExtensionGuard> {
|
pub fn new(conn: &Connection) -> Result<LoadExtensionGuard<'_>> {
|
||||||
conn.load_extension_enable()
|
conn.load_extension_enable()
|
||||||
.map(|_| LoadExtensionGuard { conn })
|
.map(|_| LoadExtensionGuard { conn })
|
||||||
}
|
}
|
||||||
|
14
src/row.rs
14
src/row.rs
@ -73,7 +73,7 @@ pub struct MappedRows<'stmt, F> {
|
|||||||
|
|
||||||
impl<'stmt, T, F> MappedRows<'stmt, F>
|
impl<'stmt, T, F> MappedRows<'stmt, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&Row) -> T,
|
F: FnMut(&Row<'_, '_>) -> T,
|
||||||
{
|
{
|
||||||
pub(crate) fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
|
pub(crate) fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
|
||||||
MappedRows { rows, map: f }
|
MappedRows { rows, map: f }
|
||||||
@ -82,7 +82,7 @@ where
|
|||||||
|
|
||||||
impl<'conn, T, F> Iterator for MappedRows<'conn, F>
|
impl<'conn, T, F> Iterator for MappedRows<'conn, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&Row) -> T,
|
F: FnMut(&Row<'_, '_>) -> T,
|
||||||
{
|
{
|
||||||
type Item = Result<T>;
|
type Item = Result<T>;
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ pub struct AndThenRows<'stmt, F> {
|
|||||||
|
|
||||||
impl<'stmt, T, E, F> AndThenRows<'stmt, F>
|
impl<'stmt, T, E, F> AndThenRows<'stmt, F>
|
||||||
where
|
where
|
||||||
F: FnMut(&Row) -> result::Result<T, E>,
|
F: FnMut(&Row<'_, '_>) -> result::Result<T, E>,
|
||||||
{
|
{
|
||||||
pub(crate) fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F> {
|
pub(crate) fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F> {
|
||||||
AndThenRows { rows, map: f }
|
AndThenRows { rows, map: f }
|
||||||
@ -113,7 +113,7 @@ where
|
|||||||
impl<'stmt, T, E, F> Iterator for AndThenRows<'stmt, F>
|
impl<'stmt, T, E, F> Iterator for AndThenRows<'stmt, F>
|
||||||
where
|
where
|
||||||
E: convert::From<Error>,
|
E: convert::From<Error>,
|
||||||
F: FnMut(&Row) -> result::Result<T, E>,
|
F: FnMut(&Row<'_, '_>) -> result::Result<T, E>,
|
||||||
{
|
{
|
||||||
type Item = result::Result<T, E>;
|
type Item = result::Result<T, E>;
|
||||||
|
|
||||||
@ -231,12 +231,12 @@ impl<'a, 'stmt> Row<'a, 'stmt> {
|
|||||||
pub trait RowIndex {
|
pub trait RowIndex {
|
||||||
/// Returns the index of the appropriate column, or `None` if no such
|
/// Returns the index of the appropriate column, or `None` if no such
|
||||||
/// column exists.
|
/// column exists.
|
||||||
fn idx(&self, stmt: &Statement) -> Result<usize>;
|
fn idx(&self, stmt: &Statement<'_>) -> Result<usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RowIndex for usize {
|
impl RowIndex for usize {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn idx(&self, stmt: &Statement) -> Result<usize> {
|
fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
|
||||||
if *self >= stmt.column_count() {
|
if *self >= stmt.column_count() {
|
||||||
Err(Error::InvalidColumnIndex(*self))
|
Err(Error::InvalidColumnIndex(*self))
|
||||||
} else {
|
} else {
|
||||||
@ -247,7 +247,7 @@ impl RowIndex for usize {
|
|||||||
|
|
||||||
impl<'a> RowIndex for &'a str {
|
impl<'a> RowIndex for &'a str {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn idx(&self, stmt: &Statement) -> Result<usize> {
|
fn idx(&self, stmt: &Statement<'_>) -> Result<usize> {
|
||||||
stmt.column_index(*self)
|
stmt.column_index(*self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ impl<'conn> Statement<'conn> {
|
|||||||
/// Will return `Err` if binding parameters fails, the executed statement
|
/// Will return `Err` if binding parameters fails, the executed statement
|
||||||
/// returns rows (in which case `query` should be used instead), or the
|
/// returns rows (in which case `query` should be used instead), or the
|
||||||
/// underling SQLite call fails.
|
/// underling SQLite call fails.
|
||||||
pub fn execute_named(&mut self, params: &[(&str, &ToSql)]) -> Result<usize> {
|
pub fn execute_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<usize> {
|
||||||
self.bind_parameters_named(params)?;
|
self.bind_parameters_named(params)?;
|
||||||
self.execute_with_bound_parameters()
|
self.execute_with_bound_parameters()
|
||||||
}
|
}
|
||||||
@ -208,7 +208,7 @@ impl<'conn> Statement<'conn> {
|
|||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if binding parameters fails.
|
/// Will return `Err` if binding parameters fails.
|
||||||
pub fn query_named<'a>(&'a mut self, params: &[(&str, &ToSql)]) -> Result<Rows<'a>> {
|
pub fn query_named<'a>(&'a mut self, params: &[(&str, &dyn ToSql)]) -> Result<Rows<'a>> {
|
||||||
self.check_readonly()?;
|
self.check_readonly()?;
|
||||||
self.bind_parameters_named(params)?;
|
self.bind_parameters_named(params)?;
|
||||||
Ok(Rows::new(self))
|
Ok(Rows::new(self))
|
||||||
@ -241,7 +241,7 @@ impl<'conn> Statement<'conn> {
|
|||||||
where
|
where
|
||||||
P: IntoIterator,
|
P: IntoIterator,
|
||||||
P::Item: ToSql,
|
P::Item: ToSql,
|
||||||
F: FnMut(&Row) -> T,
|
F: FnMut(&Row<'_, '_>) -> T,
|
||||||
{
|
{
|
||||||
let rows = self.query(params)?;
|
let rows = self.query(params)?;
|
||||||
Ok(MappedRows::new(rows, f))
|
Ok(MappedRows::new(rows, f))
|
||||||
@ -276,11 +276,11 @@ impl<'conn> Statement<'conn> {
|
|||||||
/// Will return `Err` if binding parameters fails.
|
/// Will return `Err` if binding parameters fails.
|
||||||
pub fn query_map_named<'a, T, F>(
|
pub fn query_map_named<'a, T, F>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
params: &[(&str, &ToSql)],
|
params: &[(&str, &dyn ToSql)],
|
||||||
f: F,
|
f: F,
|
||||||
) -> Result<MappedRows<'a, F>>
|
) -> Result<MappedRows<'a, F>>
|
||||||
where
|
where
|
||||||
F: FnMut(&Row) -> T,
|
F: FnMut(&Row<'_, '_>) -> T,
|
||||||
{
|
{
|
||||||
let rows = self.query_named(params)?;
|
let rows = self.query_named(params)?;
|
||||||
Ok(MappedRows::new(rows, f))
|
Ok(MappedRows::new(rows, f))
|
||||||
@ -302,7 +302,7 @@ impl<'conn> Statement<'conn> {
|
|||||||
P: IntoIterator,
|
P: IntoIterator,
|
||||||
P::Item: ToSql,
|
P::Item: ToSql,
|
||||||
E: convert::From<Error>,
|
E: convert::From<Error>,
|
||||||
F: FnMut(&Row) -> result::Result<T, E>,
|
F: FnMut(&Row<'_, '_>) -> result::Result<T, E>,
|
||||||
{
|
{
|
||||||
let rows = self.query(params)?;
|
let rows = self.query(params)?;
|
||||||
Ok(AndThenRows::new(rows, f))
|
Ok(AndThenRows::new(rows, f))
|
||||||
@ -348,12 +348,12 @@ impl<'conn> Statement<'conn> {
|
|||||||
/// Will return `Err` if binding parameters fails.
|
/// Will return `Err` if binding parameters fails.
|
||||||
pub fn query_and_then_named<'a, T, E, F>(
|
pub fn query_and_then_named<'a, T, E, F>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
params: &[(&str, &ToSql)],
|
params: &[(&str, &dyn ToSql)],
|
||||||
f: F,
|
f: F,
|
||||||
) -> Result<AndThenRows<'a, F>>
|
) -> Result<AndThenRows<'a, F>>
|
||||||
where
|
where
|
||||||
E: convert::From<Error>,
|
E: convert::From<Error>,
|
||||||
F: FnMut(&Row) -> result::Result<T, E>,
|
F: FnMut(&Row<'_, '_>) -> result::Result<T, E>,
|
||||||
{
|
{
|
||||||
let rows = self.query_named(params)?;
|
let rows = self.query_named(params)?;
|
||||||
Ok(AndThenRows::new(rows, f))
|
Ok(AndThenRows::new(rows, f))
|
||||||
@ -384,7 +384,7 @@ impl<'conn> Statement<'conn> {
|
|||||||
where
|
where
|
||||||
P: IntoIterator,
|
P: IntoIterator,
|
||||||
P::Item: ToSql,
|
P::Item: ToSql,
|
||||||
F: FnOnce(&Row) -> T,
|
F: FnOnce(&Row<'_, '_>) -> T,
|
||||||
{
|
{
|
||||||
let mut rows = self.query(params)?;
|
let mut rows = self.query(params)?;
|
||||||
|
|
||||||
@ -437,7 +437,7 @@ impl<'conn> Statement<'conn> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_parameters_named(&mut self, params: &[(&str, &ToSql)]) -> Result<()> {
|
fn bind_parameters_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<()> {
|
||||||
for &(name, value) in params {
|
for &(name, value) in params {
|
||||||
if let Some(i) = self.parameter_index(name)? {
|
if let Some(i) = self.parameter_index(name)? {
|
||||||
self.bind_parameter(value, i)?;
|
self.bind_parameter(value, i)?;
|
||||||
@ -448,7 +448,7 @@ impl<'conn> Statement<'conn> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_parameter(&self, param: &ToSql, col: usize) -> Result<()> {
|
fn bind_parameter(&self, param: &dyn ToSql, col: usize) -> Result<()> {
|
||||||
let value = param.to_sql()?;
|
let value = param.to_sql()?;
|
||||||
|
|
||||||
let ptr = unsafe { self.stmt.ptr() };
|
let ptr = unsafe { self.stmt.ptr() };
|
||||||
@ -576,7 +576,7 @@ impl<'conn> Into<RawStatement> for Statement<'conn> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'conn> fmt::Debug for Statement<'conn> {
|
impl<'conn> fmt::Debug for Statement<'conn> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let sql = str::from_utf8(self.stmt.sql().to_bytes());
|
let sql = str::from_utf8(self.stmt.sql().to_bytes());
|
||||||
f.debug_struct("Statement")
|
f.debug_struct("Statement")
|
||||||
.field("conn", self.conn)
|
.field("conn", self.conn)
|
||||||
@ -594,11 +594,11 @@ impl<'conn> Drop for Statement<'conn> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'conn> Statement<'conn> {
|
impl<'conn> Statement<'conn> {
|
||||||
pub(crate) fn new(conn: &Connection, stmt: RawStatement) -> Statement {
|
pub(crate) fn new(conn: &Connection, stmt: RawStatement) -> Statement<'_> {
|
||||||
Statement { conn, stmt }
|
Statement { conn, stmt }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn value_ref(&self, col: usize) -> ValueRef {
|
pub(crate) fn value_ref(&self, col: usize) -> ValueRef<'_> {
|
||||||
let raw = unsafe { self.stmt.ptr() };
|
let raw = unsafe { self.stmt.ptr() };
|
||||||
|
|
||||||
match self.stmt.column_type(col) {
|
match self.stmt.column_type(col) {
|
||||||
|
@ -92,7 +92,7 @@ impl<'conn> Transaction<'conn> {
|
|||||||
/// Even though we don't mutate the connection, we take a `&mut Connection`
|
/// Even though we don't mutate the connection, we take a `&mut Connection`
|
||||||
/// so as to prevent nested or concurrent transactions on the same
|
/// so as to prevent nested or concurrent transactions on the same
|
||||||
/// connection.
|
/// connection.
|
||||||
pub fn new(conn: &mut Connection, behavior: TransactionBehavior) -> Result<Transaction> {
|
pub fn new(conn: &mut Connection, behavior: TransactionBehavior) -> Result<Transaction<'_>> {
|
||||||
let query = match behavior {
|
let query = match behavior {
|
||||||
TransactionBehavior::Deferred => "BEGIN DEFERRED",
|
TransactionBehavior::Deferred => "BEGIN DEFERRED",
|
||||||
TransactionBehavior::Immediate => "BEGIN IMMEDIATE",
|
TransactionBehavior::Immediate => "BEGIN IMMEDIATE",
|
||||||
@ -131,12 +131,12 @@ impl<'conn> Transaction<'conn> {
|
|||||||
/// tx.commit()
|
/// tx.commit()
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn savepoint(&mut self) -> Result<Savepoint> {
|
pub fn savepoint(&mut self) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::with_depth(self.conn, 1)
|
Savepoint::with_depth(self.conn, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new savepoint with a custom savepoint name. See `savepoint()`.
|
/// Create a new savepoint with a custom savepoint name. See `savepoint()`.
|
||||||
pub fn savepoint_with_name<T: Into<String>>(&mut self, name: T) -> Result<Savepoint> {
|
pub fn savepoint_with_name<T: Into<String>>(&mut self, name: T) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::with_depth_and_name(self.conn, 1, name)
|
Savepoint::with_depth_and_name(self.conn, 1, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ impl<'conn> Savepoint<'conn> {
|
|||||||
conn: &Connection,
|
conn: &Connection,
|
||||||
depth: u32,
|
depth: u32,
|
||||||
name: T,
|
name: T,
|
||||||
) -> Result<Savepoint> {
|
) -> Result<Savepoint<'_>> {
|
||||||
let name = name.into();
|
let name = name.into();
|
||||||
conn.execute_batch(&format!("SAVEPOINT {}", name))
|
conn.execute_batch(&format!("SAVEPOINT {}", name))
|
||||||
.map(|_| Savepoint {
|
.map(|_| Savepoint {
|
||||||
@ -226,28 +226,28 @@ impl<'conn> Savepoint<'conn> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_depth(conn: &Connection, depth: u32) -> Result<Savepoint> {
|
fn with_depth(conn: &Connection, depth: u32) -> Result<Savepoint<'_>> {
|
||||||
let name = format!("_rusqlite_sp_{}", depth);
|
let name = format!("_rusqlite_sp_{}", depth);
|
||||||
Savepoint::with_depth_and_name(conn, depth, name)
|
Savepoint::with_depth_and_name(conn, depth, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Begin a new savepoint. Can be nested.
|
/// Begin a new savepoint. Can be nested.
|
||||||
pub fn new(conn: &mut Connection) -> Result<Savepoint> {
|
pub fn new(conn: &mut Connection) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::with_depth(conn, 0)
|
Savepoint::with_depth(conn, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Begin a new savepoint with a user-provided savepoint name.
|
/// Begin a new savepoint with a user-provided savepoint name.
|
||||||
pub fn with_name<T: Into<String>>(conn: &mut Connection, name: T) -> Result<Savepoint> {
|
pub fn with_name<T: Into<String>>(conn: &mut Connection, name: T) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::with_depth_and_name(conn, 0, name)
|
Savepoint::with_depth_and_name(conn, 0, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Begin a nested savepoint.
|
/// Begin a nested savepoint.
|
||||||
pub fn savepoint(&mut self) -> Result<Savepoint> {
|
pub fn savepoint(&mut self) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::with_depth(self.conn, self.depth + 1)
|
Savepoint::with_depth(self.conn, self.depth + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Begin a nested savepoint with a user-provided savepoint name.
|
/// Begin a nested savepoint with a user-provided savepoint name.
|
||||||
pub fn savepoint_with_name<T: Into<String>>(&mut self, name: T) -> Result<Savepoint> {
|
pub fn savepoint_with_name<T: Into<String>>(&mut self, name: T) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::with_depth_and_name(self.conn, self.depth + 1, name)
|
Savepoint::with_depth_and_name(self.conn, self.depth + 1, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +348,7 @@ impl Connection {
|
|||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if the underlying SQLite call fails.
|
/// Will return `Err` if the underlying SQLite call fails.
|
||||||
pub fn transaction(&mut self) -> Result<Transaction> {
|
pub fn transaction(&mut self) -> Result<Transaction<'_>> {
|
||||||
Transaction::new(self, TransactionBehavior::Deferred)
|
Transaction::new(self, TransactionBehavior::Deferred)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +362,7 @@ impl Connection {
|
|||||||
pub fn transaction_with_behavior(
|
pub fn transaction_with_behavior(
|
||||||
&mut self,
|
&mut self,
|
||||||
behavior: TransactionBehavior,
|
behavior: TransactionBehavior,
|
||||||
) -> Result<Transaction> {
|
) -> Result<Transaction<'_>> {
|
||||||
Transaction::new(self, behavior)
|
Transaction::new(self, behavior)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +391,7 @@ impl Connection {
|
|||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if the underlying SQLite call fails.
|
/// Will return `Err` if the underlying SQLite call fails.
|
||||||
pub fn savepoint(&mut self) -> Result<Savepoint> {
|
pub fn savepoint(&mut self) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::new(self)
|
Savepoint::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ impl Connection {
|
|||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if the underlying SQLite call fails.
|
/// Will return `Err` if the underlying SQLite call fails.
|
||||||
pub fn savepoint_with_name<T: Into<String>>(&mut self, name: T) -> Result<Savepoint> {
|
pub fn savepoint_with_name<T: Into<String>>(&mut self, name: T) -> Result<Savepoint<'_>> {
|
||||||
Savepoint::with_name(self, name)
|
Savepoint::with_name(self, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Convert most of the [Time Strings](http://sqlite.org/lang_datefunc.html) to chrono types.
|
//! Convert most of the [Time Strings](http://sqlite.org/lang_datefunc.html) to chrono types.
|
||||||
extern crate chrono;
|
use chrono;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ use crate::Result;
|
|||||||
|
|
||||||
/// ISO 8601 calendar date without timezone => "YYYY-MM-DD"
|
/// ISO 8601 calendar date without timezone => "YYYY-MM-DD"
|
||||||
impl ToSql for NaiveDate {
|
impl ToSql for NaiveDate {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
let date_str = self.format("%Y-%m-%d").to_string();
|
let date_str = self.format("%Y-%m-%d").to_string();
|
||||||
Ok(ToSqlOutput::from(date_str))
|
Ok(ToSqlOutput::from(date_str))
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ impl ToSql for NaiveDate {
|
|||||||
|
|
||||||
/// "YYYY-MM-DD" => ISO 8601 calendar date without timezone.
|
/// "YYYY-MM-DD" => ISO 8601 calendar date without timezone.
|
||||||
impl FromSql for NaiveDate {
|
impl FromSql for NaiveDate {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value
|
value
|
||||||
.as_str()
|
.as_str()
|
||||||
.and_then(|s| match NaiveDate::parse_from_str(s, "%Y-%m-%d") {
|
.and_then(|s| match NaiveDate::parse_from_str(s, "%Y-%m-%d") {
|
||||||
@ -30,7 +30,7 @@ impl FromSql for NaiveDate {
|
|||||||
|
|
||||||
/// ISO 8601 time without timezone => "HH:MM:SS.SSS"
|
/// ISO 8601 time without timezone => "HH:MM:SS.SSS"
|
||||||
impl ToSql for NaiveTime {
|
impl ToSql for NaiveTime {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
let date_str = self.format("%H:%M:%S%.f").to_string();
|
let date_str = self.format("%H:%M:%S%.f").to_string();
|
||||||
Ok(ToSqlOutput::from(date_str))
|
Ok(ToSqlOutput::from(date_str))
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ impl ToSql for NaiveTime {
|
|||||||
|
|
||||||
/// "HH:MM"/"HH:MM:SS"/"HH:MM:SS.SSS" => ISO 8601 time without timezone.
|
/// "HH:MM"/"HH:MM:SS"/"HH:MM:SS.SSS" => ISO 8601 time without timezone.
|
||||||
impl FromSql for NaiveTime {
|
impl FromSql for NaiveTime {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value.as_str().and_then(|s| {
|
value.as_str().and_then(|s| {
|
||||||
let fmt = match s.len() {
|
let fmt = match s.len() {
|
||||||
5 => "%H:%M",
|
5 => "%H:%M",
|
||||||
@ -56,7 +56,7 @@ impl FromSql for NaiveTime {
|
|||||||
/// ISO 8601 combined date and time without timezone =>
|
/// ISO 8601 combined date and time without timezone =>
|
||||||
/// "YYYY-MM-DD HH:MM:SS.SSS"
|
/// "YYYY-MM-DD HH:MM:SS.SSS"
|
||||||
impl ToSql for NaiveDateTime {
|
impl ToSql for NaiveDateTime {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
let date_str = self.format("%Y-%m-%dT%H:%M:%S%.f").to_string();
|
let date_str = self.format("%Y-%m-%dT%H:%M:%S%.f").to_string();
|
||||||
Ok(ToSqlOutput::from(date_str))
|
Ok(ToSqlOutput::from(date_str))
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ impl ToSql for NaiveDateTime {
|
|||||||
/// and time without timezone. ("YYYY-MM-DDTHH:MM:SS"/"YYYY-MM-DDTHH:MM:SS.SSS"
|
/// and time without timezone. ("YYYY-MM-DDTHH:MM:SS"/"YYYY-MM-DDTHH:MM:SS.SSS"
|
||||||
/// also supported)
|
/// also supported)
|
||||||
impl FromSql for NaiveDateTime {
|
impl FromSql for NaiveDateTime {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value.as_str().and_then(|s| {
|
value.as_str().and_then(|s| {
|
||||||
let fmt = if s.len() >= 11 && s.as_bytes()[10] == b'T' {
|
let fmt = if s.len() >= 11 && s.as_bytes()[10] == b'T' {
|
||||||
"%Y-%m-%dT%H:%M:%S%.f"
|
"%Y-%m-%dT%H:%M:%S%.f"
|
||||||
@ -85,14 +85,14 @@ impl FromSql for NaiveDateTime {
|
|||||||
/// Date and time with time zone => UTC RFC3339 timestamp
|
/// Date and time with time zone => UTC RFC3339 timestamp
|
||||||
/// ("YYYY-MM-DDTHH:MM:SS.SSS+00:00").
|
/// ("YYYY-MM-DDTHH:MM:SS.SSS+00:00").
|
||||||
impl<Tz: TimeZone> ToSql for DateTime<Tz> {
|
impl<Tz: TimeZone> ToSql for DateTime<Tz> {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(self.with_timezone(&Utc).to_rfc3339()))
|
Ok(ToSqlOutput::from(self.with_timezone(&Utc).to_rfc3339()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RFC3339 ("YYYY-MM-DDTHH:MM:SS.SSS[+-]HH:MM") into `DateTime<Utc>`.
|
/// RFC3339 ("YYYY-MM-DDTHH:MM:SS.SSS[+-]HH:MM") into `DateTime<Utc>`.
|
||||||
impl FromSql for DateTime<Utc> {
|
impl FromSql for DateTime<Utc> {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
{
|
{
|
||||||
// Try to parse value as rfc3339 first.
|
// Try to parse value as rfc3339 first.
|
||||||
let s = value.as_str()?;
|
let s = value.as_str()?;
|
||||||
@ -121,7 +121,7 @@ impl FromSql for DateTime<Utc> {
|
|||||||
|
|
||||||
/// RFC3339 ("YYYY-MM-DDTHH:MM:SS.SSS[+-]HH:MM") into `DateTime<Local>`.
|
/// RFC3339 ("YYYY-MM-DDTHH:MM:SS.SSS[+-]HH:MM") into `DateTime<Local>`.
|
||||||
impl FromSql for DateTime<Local> {
|
impl FromSql for DateTime<Local> {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
let utc_dt = DateTime::<Utc>::column_result(value)?;
|
let utc_dt = DateTime::<Utc>::column_result(value)?;
|
||||||
Ok(utc_dt.with_timezone(&Local))
|
Ok(utc_dt.with_timezone(&Local))
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,11 @@ pub enum FromSqlError {
|
|||||||
InvalidI128Size(usize),
|
InvalidI128Size(usize),
|
||||||
|
|
||||||
/// An error case available for implementors of the `FromSql` trait.
|
/// An error case available for implementors of the `FromSql` trait.
|
||||||
Other(Box<Error + Send + Sync>),
|
Other(Box<dyn Error + Send + Sync>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for FromSqlError {
|
impl fmt::Display for FromSqlError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
FromSqlError::InvalidType => write!(f, "Invalid type"),
|
FromSqlError::InvalidType => write!(f, "Invalid type"),
|
||||||
FromSqlError::OutOfRange(i) => write!(f, "Value {} out of range", i),
|
FromSqlError::OutOfRange(i) => write!(f, "Value {} out of range", i),
|
||||||
@ -48,7 +48,7 @@ impl Error for FromSqlError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::match_same_arms)]
|
#[allow(clippy::match_same_arms)]
|
||||||
fn cause(&self) -> Option<&Error> {
|
fn cause(&self) -> Option<&dyn Error> {
|
||||||
match *self {
|
match *self {
|
||||||
FromSqlError::Other(ref err) => err.cause(),
|
FromSqlError::Other(ref err) => err.cause(),
|
||||||
FromSqlError::InvalidType | FromSqlError::OutOfRange(_) => None,
|
FromSqlError::InvalidType | FromSqlError::OutOfRange(_) => None,
|
||||||
@ -73,11 +73,11 @@ pub type FromSqlResult<T> = Result<T, FromSqlError>;
|
|||||||
/// fetching values as i64 and then doing the interpretation themselves or by
|
/// fetching values as i64 and then doing the interpretation themselves or by
|
||||||
/// defining a newtype and implementing `FromSql`/`ToSql` for it.
|
/// defining a newtype and implementing `FromSql`/`ToSql` for it.
|
||||||
pub trait FromSql: Sized {
|
pub trait FromSql: Sized {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self>;
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for isize {
|
impl FromSql for isize {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
i64::column_result(value).and_then(|i| {
|
i64::column_result(value).and_then(|i| {
|
||||||
if i < isize::min_value() as i64 || i > isize::max_value() as i64 {
|
if i < isize::min_value() as i64 || i > isize::max_value() as i64 {
|
||||||
Err(FromSqlError::OutOfRange(i))
|
Err(FromSqlError::OutOfRange(i))
|
||||||
@ -91,7 +91,7 @@ impl FromSql for isize {
|
|||||||
macro_rules! from_sql_integral(
|
macro_rules! from_sql_integral(
|
||||||
($t:ident) => (
|
($t:ident) => (
|
||||||
impl FromSql for $t {
|
impl FromSql for $t {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
i64::column_result(value).and_then(|i| {
|
i64::column_result(value).and_then(|i| {
|
||||||
if i < i64::from($t::min_value()) || i > i64::from($t::max_value()) {
|
if i < i64::from($t::min_value()) || i > i64::from($t::max_value()) {
|
||||||
Err(FromSqlError::OutOfRange(i))
|
Err(FromSqlError::OutOfRange(i))
|
||||||
@ -112,13 +112,13 @@ from_sql_integral!(u16);
|
|||||||
from_sql_integral!(u32);
|
from_sql_integral!(u32);
|
||||||
|
|
||||||
impl FromSql for i64 {
|
impl FromSql for i64 {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value.as_i64()
|
value.as_i64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for f64 {
|
impl FromSql for f64 {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
match value {
|
match value {
|
||||||
ValueRef::Integer(i) => Ok(i as f64),
|
ValueRef::Integer(i) => Ok(i as f64),
|
||||||
ValueRef::Real(f) => Ok(f),
|
ValueRef::Real(f) => Ok(f),
|
||||||
@ -128,7 +128,7 @@ impl FromSql for f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for bool {
|
impl FromSql for bool {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
i64::column_result(value).map(|i| match i {
|
i64::column_result(value).map(|i| match i {
|
||||||
0 => false,
|
0 => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
@ -137,20 +137,20 @@ impl FromSql for bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for String {
|
impl FromSql for String {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value.as_str().map(|s| s.to_string())
|
value.as_str().map(|s| s.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for Vec<u8> {
|
impl FromSql for Vec<u8> {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value.as_blob().map(|b| b.to_vec())
|
value.as_blob().map(|b| b.to_vec())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "i128_blob")]
|
#[cfg(feature = "i128_blob")]
|
||||||
impl FromSql for i128 {
|
impl FromSql for i128 {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
|
|
||||||
value.as_blob().and_then(|bytes| {
|
value.as_blob().and_then(|bytes| {
|
||||||
@ -164,7 +164,7 @@ impl FromSql for i128 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FromSql> FromSql for Option<T> {
|
impl<T: FromSql> FromSql for Option<T> {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
match value {
|
match value {
|
||||||
ValueRef::Null => Ok(None),
|
ValueRef::Null => Ok(None),
|
||||||
_ => FromSql::column_result(value).map(Some),
|
_ => FromSql::column_result(value).map(Some),
|
||||||
@ -173,7 +173,7 @@ impl<T: FromSql> FromSql for Option<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for Value {
|
impl FromSql for Value {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
Ok(value.into())
|
Ok(value.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ pub enum Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Type {
|
impl fmt::Display for Type {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Type::Null => write!(f, "Null"),
|
Type::Null => write!(f, "Null"),
|
||||||
Type::Integer => write!(f, "Integer"),
|
Type::Integer => write!(f, "Integer"),
|
||||||
@ -111,7 +111,7 @@ impl fmt::Display for Type {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
extern crate time;
|
use time;
|
||||||
|
|
||||||
use super::Value;
|
use super::Value;
|
||||||
use crate::{Connection, Error, NO_PARAMS};
|
use crate::{Connection, Error, NO_PARAMS};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! `ToSql` and `FromSql` implementation for JSON `Value`.
|
//! `ToSql` and `FromSql` implementation for JSON `Value`.
|
||||||
extern crate serde_json;
|
use serde_json;
|
||||||
|
|
||||||
use self::serde_json::Value;
|
use self::serde_json::Value;
|
||||||
|
|
||||||
@ -8,14 +8,14 @@ use crate::Result;
|
|||||||
|
|
||||||
/// Serialize JSON `Value` to text.
|
/// Serialize JSON `Value` to text.
|
||||||
impl ToSql for Value {
|
impl ToSql for Value {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(serde_json::to_string(self).unwrap()))
|
Ok(ToSqlOutput::from(serde_json::to_string(self).unwrap()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize text/blob to JSON `Value`.
|
/// Deserialize text/blob to JSON `Value`.
|
||||||
impl FromSql for Value {
|
impl FromSql for Value {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
match value {
|
match value {
|
||||||
ValueRef::Text(s) => serde_json::from_str(s),
|
ValueRef::Text(s) => serde_json::from_str(s),
|
||||||
ValueRef::Blob(b) => serde_json::from_slice(b),
|
ValueRef::Blob(b) => serde_json::from_slice(b),
|
||||||
@ -46,7 +46,7 @@ mod test {
|
|||||||
let data: serde_json::Value = serde_json::from_str(json).unwrap();
|
let data: serde_json::Value = serde_json::from_str(json).unwrap();
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO foo (t, b) VALUES (?, ?)",
|
"INSERT INTO foo (t, b) VALUES (?, ?)",
|
||||||
&[&data as &ToSql, &json.as_bytes()],
|
&[&data as &dyn ToSql, &json.as_bytes()],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
extern crate time;
|
use time;
|
||||||
|
|
||||||
use crate::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
|
use crate::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
@ -8,7 +8,7 @@ const SQLITE_DATETIME_FMT: &str = "%Y-%m-%dT%H:%M:%S.%fZ";
|
|||||||
const SQLITE_DATETIME_FMT_LEGACY: &str = "%Y-%m-%d %H:%M:%S:%f %Z";
|
const SQLITE_DATETIME_FMT_LEGACY: &str = "%Y-%m-%d %H:%M:%S:%f %Z";
|
||||||
|
|
||||||
impl ToSql for time::Timespec {
|
impl ToSql for time::Timespec {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
let time_string = time::at_utc(*self)
|
let time_string = time::at_utc(*self)
|
||||||
.strftime(SQLITE_DATETIME_FMT)
|
.strftime(SQLITE_DATETIME_FMT)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -18,7 +18,7 @@ impl ToSql for time::Timespec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql for time::Timespec {
|
impl FromSql for time::Timespec {
|
||||||
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value
|
value
|
||||||
.as_str()
|
.as_str()
|
||||||
.and_then(|s| {
|
.and_then(|s| {
|
||||||
|
@ -66,7 +66,7 @@ from_value!(Vec<u8>);
|
|||||||
from_value!(i128);
|
from_value!(i128);
|
||||||
|
|
||||||
impl<'a> ToSql for ToSqlOutput<'a> {
|
impl<'a> ToSql for ToSqlOutput<'a> {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(match *self {
|
Ok(match *self {
|
||||||
ToSqlOutput::Borrowed(v) => ToSqlOutput::Borrowed(v),
|
ToSqlOutput::Borrowed(v) => ToSqlOutput::Borrowed(v),
|
||||||
ToSqlOutput::Owned(ref v) => ToSqlOutput::Borrowed(ValueRef::from(v)),
|
ToSqlOutput::Owned(ref v) => ToSqlOutput::Borrowed(ValueRef::from(v)),
|
||||||
@ -81,7 +81,7 @@ impl<'a> ToSql for ToSqlOutput<'a> {
|
|||||||
|
|
||||||
/// A trait for types that can be converted into SQLite values.
|
/// A trait for types that can be converted into SQLite values.
|
||||||
pub trait ToSql {
|
pub trait ToSql {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput>;
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should be able to use a generic impl like this:
|
// We should be able to use a generic impl like this:
|
||||||
@ -99,7 +99,7 @@ pub trait ToSql {
|
|||||||
macro_rules! to_sql_self(
|
macro_rules! to_sql_self(
|
||||||
($t:ty) => (
|
($t:ty) => (
|
||||||
impl ToSql for $t {
|
impl ToSql for $t {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(*self))
|
Ok(ToSqlOutput::from(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,43 +125,43 @@ impl<'a, T: ?Sized> ToSql for &'a T
|
|||||||
where
|
where
|
||||||
T: ToSql,
|
T: ToSql,
|
||||||
{
|
{
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
(*self).to_sql()
|
(*self).to_sql()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSql for String {
|
impl ToSql for String {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(self.as_str()))
|
Ok(ToSqlOutput::from(self.as_str()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSql for str {
|
impl ToSql for str {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(self))
|
Ok(ToSqlOutput::from(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSql for Vec<u8> {
|
impl ToSql for Vec<u8> {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(self.as_slice()))
|
Ok(ToSqlOutput::from(self.as_slice()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSql for [u8] {
|
impl ToSql for [u8] {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(self))
|
Ok(ToSqlOutput::from(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSql for Value {
|
impl ToSql for Value {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(self))
|
Ok(ToSqlOutput::from(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ToSql> ToSql for Option<T> {
|
impl<T: ToSql> ToSql for Option<T> {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
match *self {
|
match *self {
|
||||||
None => Ok(ToSqlOutput::from(Null)),
|
None => Ok(ToSqlOutput::from(Null)),
|
||||||
Some(ref t) => t.to_sql(),
|
Some(ref t) => t.to_sql(),
|
||||||
@ -170,7 +170,7 @@ impl<T: ToSql> ToSql for Option<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ToSql for Cow<'a, str> {
|
impl<'a> ToSql for Cow<'a, str> {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(self.as_ref()))
|
Ok(ToSqlOutput::from(self.as_ref()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ impl<'a> ValueRef<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<ValueRef<'a>> for Value {
|
impl<'a> From<ValueRef<'a>> for Value {
|
||||||
fn from(borrowed: ValueRef) -> Value {
|
fn from(borrowed: ValueRef<'_>) -> Value {
|
||||||
match borrowed {
|
match borrowed {
|
||||||
ValueRef::Null => Value::Null,
|
ValueRef::Null => Value::Null,
|
||||||
ValueRef::Integer(i) => Value::Integer(i),
|
ValueRef::Integer(i) => Value::Integer(i),
|
||||||
@ -82,13 +82,13 @@ impl<'a> From<ValueRef<'a>> for Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a str> for ValueRef<'a> {
|
impl<'a> From<&'a str> for ValueRef<'a> {
|
||||||
fn from(s: &str) -> ValueRef {
|
fn from(s: &str) -> ValueRef<'_> {
|
||||||
ValueRef::Text(s)
|
ValueRef::Text(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a [u8]> for ValueRef<'a> {
|
impl<'a> From<&'a [u8]> for ValueRef<'a> {
|
||||||
fn from(s: &[u8]) -> ValueRef {
|
fn from(s: &[u8]) -> ValueRef<'_> {
|
||||||
ValueRef::Blob(s)
|
ValueRef::Blob(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ pub(crate) unsafe extern "C" fn free_array(p: *mut c_void) {
|
|||||||
pub type Array = Rc<Vec<Value>>;
|
pub type Array = Rc<Vec<Value>>;
|
||||||
|
|
||||||
impl ToSql for Array {
|
impl ToSql for Array {
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::Array(self.clone()))
|
Ok(ToSqlOutput::Array(self.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ impl ArrayTabCursor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl VTabCursor for ArrayTabCursor {
|
impl VTabCursor for ArrayTabCursor {
|
||||||
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values) -> Result<()> {
|
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values<'_>) -> Result<()> {
|
||||||
if idx_num > 0 {
|
if idx_num > 0 {
|
||||||
self.ptr = args.get_array(0)?;
|
self.ptr = args.get_array(0)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! CSV Virtual Table.
|
//! CSV Virtual Table.
|
||||||
//!
|
//!
|
||||||
//! Port of [csv](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/csv.c) C extension.
|
//! Port of [csv](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/csv.c) C extension.
|
||||||
extern crate csv;
|
use csv;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -285,7 +285,12 @@ impl CSVTabCursor {
|
|||||||
impl VTabCursor for CSVTabCursor {
|
impl VTabCursor for CSVTabCursor {
|
||||||
// Only a full table scan is supported. So `filter` simply rewinds to
|
// Only a full table scan is supported. So `filter` simply rewinds to
|
||||||
// the beginning.
|
// the beginning.
|
||||||
fn filter(&mut self, _idx_num: c_int, _idx_str: Option<&str>, _args: &Values) -> Result<()> {
|
fn filter(
|
||||||
|
&mut self,
|
||||||
|
_idx_num: c_int,
|
||||||
|
_idx_str: Option<&str>,
|
||||||
|
_args: &Values<'_>,
|
||||||
|
) -> Result<()> {
|
||||||
{
|
{
|
||||||
let offset_first_row = self.vtab().offset_first_row.clone();
|
let offset_first_row = self.vtab().offset_first_row.clone();
|
||||||
self.reader.seek(offset_first_row)?;
|
self.reader.seek(offset_first_row)?;
|
||||||
|
@ -250,7 +250,7 @@ pub struct IndexInfo(*mut ffi::sqlite3_index_info);
|
|||||||
|
|
||||||
impl IndexInfo {
|
impl IndexInfo {
|
||||||
/// Record WHERE clause constraints.
|
/// Record WHERE clause constraints.
|
||||||
pub fn constraints(&self) -> IndexConstraintIter {
|
pub fn constraints(&self) -> IndexConstraintIter<'_> {
|
||||||
let constraints =
|
let constraints =
|
||||||
unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
|
unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
|
||||||
IndexConstraintIter {
|
IndexConstraintIter {
|
||||||
@ -259,7 +259,7 @@ impl IndexInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Information about the ORDER BY clause.
|
/// Information about the ORDER BY clause.
|
||||||
pub fn order_bys(&self) -> OrderByIter {
|
pub fn order_bys(&self) -> OrderByIter<'_> {
|
||||||
let order_bys =
|
let order_bys =
|
||||||
unsafe { slice::from_raw_parts((*self.0).aOrderBy, (*self.0).nOrderBy as usize) };
|
unsafe { slice::from_raw_parts((*self.0).aOrderBy, (*self.0).nOrderBy as usize) };
|
||||||
OrderByIter {
|
OrderByIter {
|
||||||
@ -272,7 +272,7 @@ impl IndexInfo {
|
|||||||
unsafe { (*self.0).nOrderBy as usize }
|
unsafe { (*self.0).nOrderBy as usize }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn constraint_usage(&mut self, constraint_idx: usize) -> IndexConstraintUsage {
|
pub fn constraint_usage(&mut self, constraint_idx: usize) -> IndexConstraintUsage<'_> {
|
||||||
let constraint_usages = unsafe {
|
let constraint_usages = unsafe {
|
||||||
slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
|
slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
|
||||||
};
|
};
|
||||||
@ -412,7 +412,7 @@ impl<'a> OrderBy<'a> {
|
|||||||
pub trait VTabCursor: Sized {
|
pub trait VTabCursor: Sized {
|
||||||
/// Begin a search of a virtual table.
|
/// Begin a search of a virtual table.
|
||||||
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xfilter_method))
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xfilter_method))
|
||||||
fn filter(&mut self, idx_num: c_int, idx_str: Option<&str>, args: &Values) -> Result<()>;
|
fn filter(&mut self, idx_num: c_int, idx_str: Option<&str>, args: &Values<'_>) -> Result<()>;
|
||||||
/// Advance cursor to the next row of a result set initiated by `filter`.
|
/// Advance cursor to the next row of a result set initiated by `filter`.
|
||||||
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xnext_method))
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xnext_method))
|
||||||
fn next(&mut self) -> Result<()>;
|
fn next(&mut self) -> Result<()>;
|
||||||
@ -491,7 +491,7 @@ impl<'a> Values<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self) -> ValueIter {
|
pub fn iter(&self) -> ValueIter<'_> {
|
||||||
ValueIter {
|
ValueIter {
|
||||||
iter: self.args.iter(),
|
iter: self.args.iter(),
|
||||||
}
|
}
|
||||||
@ -575,7 +575,7 @@ impl InnerConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Escape double-quote (`"`) character occurences by doubling them (`""`).
|
/// Escape double-quote (`"`) character occurences by doubling them (`""`).
|
||||||
pub fn escape_double_quote(identifier: &str) -> Cow<str> {
|
pub fn escape_double_quote(identifier: &str) -> Cow<'_, str> {
|
||||||
if identifier.contains('"') {
|
if identifier.contains('"') {
|
||||||
// escape quote by doubling them
|
// escape quote by doubling them
|
||||||
Owned(identifier.replace("\"", "\"\""))
|
Owned(identifier.replace("\"", "\"\""))
|
||||||
|
@ -184,7 +184,7 @@ impl SeriesTabCursor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl VTabCursor for SeriesTabCursor {
|
impl VTabCursor for SeriesTabCursor {
|
||||||
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values) -> Result<()> {
|
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values<'_>) -> Result<()> {
|
||||||
let idx_num = QueryPlanFlags::from_bits_truncate(idx_num);
|
let idx_num = QueryPlanFlags::from_bits_truncate(idx_num);
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
if idx_num.contains(QueryPlanFlags::START) {
|
if idx_num.contains(QueryPlanFlags::START) {
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
extern crate rusqlite;
|
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
//! Ensure we reject connections when SQLite is in single-threaded mode, as it
|
//! Ensure we reject connections when SQLite is in single-threaded mode, as it
|
||||||
//! would violate safety if multiple Rust threads tried to use connections.
|
//! would violate safety if multiple Rust threads tried to use connections.
|
||||||
|
|
||||||
extern crate libsqlite3_sys as ffi;
|
use libsqlite3_sys as ffi;
|
||||||
extern crate rusqlite;
|
|
||||||
|
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
//! Ensure Virtual tables can be declared outside `rusqlite` crate.
|
//! Ensure Virtual tables can be declared outside `rusqlite` crate.
|
||||||
|
|
||||||
#[cfg(feature = "vtab")]
|
|
||||||
extern crate rusqlite;
|
|
||||||
|
|
||||||
#[cfg(feature = "vtab")]
|
#[cfg(feature = "vtab")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dummy_module() {
|
fn test_dummy_module() {
|
||||||
@ -61,7 +58,7 @@ fn test_dummy_module() {
|
|||||||
&mut self,
|
&mut self,
|
||||||
_idx_num: c_int,
|
_idx_num: c_int,
|
||||||
_idx_str: Option<&str>,
|
_idx_str: Option<&str>,
|
||||||
_args: &Values,
|
_args: &Values<'_>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.row_id = 1;
|
self.row_id = 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -98,7 +95,7 @@ fn test_dummy_module() {
|
|||||||
let mut s = db.prepare("SELECT * FROM dummy()").unwrap();
|
let mut s = db.prepare("SELECT * FROM dummy()").unwrap();
|
||||||
|
|
||||||
let dummy = s
|
let dummy = s
|
||||||
.query_row(&[] as &[&ToSql], |row| row.get::<_, i32>(0))
|
.query_row(&[] as &[&dyn ToSql], |row| row.get::<_, i32>(0))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(1, dummy);
|
assert_eq!(1, dummy);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user