Add #[inline] and #[cold] in far more places

This commit is contained in:
Thom Chiovoloni 2020-11-03 19:10:23 -08:00
parent 7574124233
commit 65c38bf813
36 changed files with 366 additions and 32 deletions

View File

@ -180,6 +180,7 @@ impl Backup<'_, '_> {
/// ///
/// Will return `Err` if the underlying `sqlite3_backup_init` call returns /// Will return `Err` if the underlying `sqlite3_backup_init` call returns
/// `NULL`. /// `NULL`.
#[inline]
pub fn new<'a, 'b>(from: &'a Connection, to: &'b mut Connection) -> Result<Backup<'a, 'b>> { pub fn new<'a, 'b>(from: &'a Connection, to: &'b mut Connection) -> Result<Backup<'a, 'b>> {
Backup::new_with_names(from, DatabaseName::Main, to, DatabaseName::Main) Backup::new_with_names(from, DatabaseName::Main, to, DatabaseName::Main)
} }
@ -225,6 +226,7 @@ impl Backup<'_, '_> {
} }
/// Gets the progress of the backup as of the last call to `step`. /// Gets the progress of the backup as of the last call to `step`.
#[inline]
pub fn progress(&self) -> Progress { pub fn progress(&self) -> Progress {
unsafe { unsafe {
Progress { Progress {
@ -246,6 +248,7 @@ impl Backup<'_, '_> {
/// an error code other than `DONE`, `OK`, `BUSY`, or `LOCKED`. `BUSY` and /// an error code other than `DONE`, `OK`, `BUSY`, or `LOCKED`. `BUSY` and
/// `LOCKED` are transient errors and are therefore returned as possible /// `LOCKED` are transient errors and are therefore returned as possible
/// `Ok` values. /// `Ok` values.
#[inline]
pub fn step(&self, num_pages: c_int) -> Result<StepResult> { pub fn step(&self, num_pages: c_int) -> Result<StepResult> {
use self::StepResult::{Busy, Done, Locked, More}; use self::StepResult::{Busy, Done, Locked, More};
@ -298,6 +301,7 @@ impl Backup<'_, '_> {
} }
impl Drop for Backup<'_, '_> { impl Drop for Backup<'_, '_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { ffi::sqlite3_backup_finish(self.b) }; unsafe { ffi::sqlite3_backup_finish(self.b) };
} }

View File

@ -214,6 +214,7 @@ impl Connection {
/// Will return `Err` if `db`/`table`/`column` cannot be converted to a /// Will return `Err` if `db`/`table`/`column` cannot be converted to a
/// C-compatible string or if the underlying SQLite BLOB open call /// C-compatible string or if the underlying SQLite BLOB open call
/// fails. /// fails.
#[inline]
pub fn blob_open<'a>( pub fn blob_open<'a>(
&'a self, &'a self,
db: DatabaseName<'_>, db: DatabaseName<'_>,
@ -252,6 +253,7 @@ impl Blob<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite BLOB reopen call fails. /// Will return `Err` if the underlying SQLite BLOB reopen call fails.
#[inline]
pub fn reopen(&mut self, row: i64) -> Result<()> { pub fn reopen(&mut self, row: i64) -> Result<()> {
let rc = unsafe { ffi::sqlite3_blob_reopen(self.blob, row) }; let rc = unsafe { ffi::sqlite3_blob_reopen(self.blob, row) };
if rc != ffi::SQLITE_OK { if rc != ffi::SQLITE_OK {
@ -262,17 +264,20 @@ impl Blob<'_> {
} }
/// Return the size in bytes of the BLOB. /// Return the size in bytes of the BLOB.
#[inline]
pub fn size(&self) -> i32 { pub fn size(&self) -> i32 {
unsafe { ffi::sqlite3_blob_bytes(self.blob) } unsafe { ffi::sqlite3_blob_bytes(self.blob) }
} }
/// Return the current size in bytes of the BLOB. /// Return the current size in bytes of the BLOB.
#[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
use std::convert::TryInto; use std::convert::TryInto;
self.size().try_into().unwrap() self.size().try_into().unwrap()
} }
/// Return true if the BLOB is empty. /// Return true if the BLOB is empty.
#[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.size() == 0 self.size() == 0
} }
@ -286,10 +291,12 @@ impl Blob<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite close call fails. /// Will return `Err` if the underlying SQLite close call fails.
#[inline]
pub fn close(mut self) -> Result<()> { pub fn close(mut self) -> Result<()> {
self.close_() self.close_()
} }
#[inline]
fn close_(&mut self) -> Result<()> { fn close_(&mut self) -> Result<()> {
let rc = unsafe { ffi::sqlite3_blob_close(self.blob) }; let rc = unsafe { ffi::sqlite3_blob_close(self.blob) };
self.blob = ptr::null_mut(); self.blob = ptr::null_mut();
@ -304,6 +311,7 @@ impl io::Read for Blob<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite read call fails. /// Will return `Err` if the underlying SQLite read call fails.
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let max_allowed_len = (self.size() - self.pos) as usize; let max_allowed_len = (self.size() - self.pos) as usize;
let n = min(buf.len(), max_allowed_len) as i32; let n = min(buf.len(), max_allowed_len) as i32;
@ -334,6 +342,7 @@ impl io::Write for Blob<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite write call fails. /// Will return `Err` if the underlying SQLite write call fails.
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let max_allowed_len = (self.size() - self.pos) as usize; let max_allowed_len = (self.size() - self.pos) as usize;
let n = min(buf.len(), max_allowed_len) as i32; let n = min(buf.len(), max_allowed_len) as i32;
@ -350,6 +359,7 @@ impl io::Write for Blob<'_> {
.map_err(|err| io::Error::new(io::ErrorKind::Other, err)) .map_err(|err| io::Error::new(io::ErrorKind::Other, err))
} }
#[inline]
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
Ok(()) Ok(())
} }
@ -357,6 +367,7 @@ impl io::Write for Blob<'_> {
impl io::Seek for Blob<'_> { impl io::Seek for Blob<'_> {
/// Seek to an offset, in bytes, in BLOB. /// Seek to an offset, in bytes, in BLOB.
#[inline]
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> { fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
let pos = match pos { let pos = match pos {
io::SeekFrom::Start(offset) => offset as i64, io::SeekFrom::Start(offset) => offset as i64,
@ -383,6 +394,7 @@ impl io::Seek for Blob<'_> {
#[allow(unused_must_use)] #[allow(unused_must_use)]
impl Drop for Blob<'_> { impl Drop for Blob<'_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.close_(); self.close_();
} }
@ -398,6 +410,7 @@ impl Drop for Blob<'_> {
pub struct ZeroBlob(pub i32); pub struct ZeroBlob(pub i32);
impl ToSql for ZeroBlob { impl ToSql for ZeroBlob {
#[inline]
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))

View File

@ -69,6 +69,7 @@ impl Connection {
} }
impl InnerConnection { impl InnerConnection {
#[inline]
fn busy_timeout(&mut self, timeout: c_int) -> Result<()> { fn busy_timeout(&mut self, timeout: c_int) -> Result<()> {
let r = unsafe { ffi::sqlite3_busy_timeout(self.db, timeout) }; let r = unsafe { ffi::sqlite3_busy_timeout(self.db, timeout) };
self.decode_result(r) self.decode_result(r)

View File

@ -34,6 +34,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.
#[inline]
pub fn prepare_cached(&self, sql: &str) -> Result<CachedStatement<'_>> { pub fn prepare_cached(&self, sql: &str) -> Result<CachedStatement<'_>> {
self.cache.get(self, sql) self.cache.get(self, sql)
} }
@ -43,11 +44,13 @@ impl Connection {
/// number of cached statements. If you need more, or know that you /// number of cached statements. If you need more, or know that you
/// will not use cached statements, you /// will not use cached statements, you
/// can set the capacity manually using this method. /// can set the capacity manually using this method.
#[inline]
pub fn set_prepared_statement_cache_capacity(&self, capacity: usize) { pub fn set_prepared_statement_cache_capacity(&self, capacity: usize) {
self.cache.set_capacity(capacity) self.cache.set_capacity(capacity)
} }
/// Remove/finalize all prepared statements currently in the cache. /// Remove/finalize all prepared statements currently in the cache.
#[inline]
pub fn flush_prepared_statement_cache(&self) { pub fn flush_prepared_statement_cache(&self) {
self.cache.flush() self.cache.flush()
} }
@ -69,12 +72,14 @@ pub struct CachedStatement<'conn> {
impl<'conn> Deref for CachedStatement<'conn> { impl<'conn> Deref for CachedStatement<'conn> {
type Target = Statement<'conn>; type Target = Statement<'conn>;
#[inline]
fn deref(&self) -> &Statement<'conn> { fn deref(&self) -> &Statement<'conn> {
self.stmt.as_ref().unwrap() self.stmt.as_ref().unwrap()
} }
} }
impl<'conn> DerefMut for CachedStatement<'conn> { impl<'conn> DerefMut for CachedStatement<'conn> {
#[inline]
fn deref_mut(&mut self) -> &mut Statement<'conn> { fn deref_mut(&mut self) -> &mut Statement<'conn> {
self.stmt.as_mut().unwrap() self.stmt.as_mut().unwrap()
} }
@ -82,6 +87,7 @@ impl<'conn> DerefMut for CachedStatement<'conn> {
impl Drop for CachedStatement<'_> { impl Drop for CachedStatement<'_> {
#[allow(unused_must_use)] #[allow(unused_must_use)]
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
if let Some(stmt) = self.stmt.take() { if let Some(stmt) = self.stmt.take() {
self.cache.cache_stmt(unsafe { stmt.into_raw() }); self.cache.cache_stmt(unsafe { stmt.into_raw() });
@ -90,6 +96,7 @@ impl Drop for CachedStatement<'_> {
} }
impl CachedStatement<'_> { impl CachedStatement<'_> {
#[inline]
fn new<'conn>(stmt: Statement<'conn>, cache: &'conn StatementCache) -> CachedStatement<'conn> { fn new<'conn>(stmt: Statement<'conn>, cache: &'conn StatementCache) -> CachedStatement<'conn> {
CachedStatement { CachedStatement {
stmt: Some(stmt), stmt: Some(stmt),
@ -99,6 +106,7 @@ impl CachedStatement<'_> {
/// Discard the statement, preventing it from being returned to its /// Discard the statement, preventing it from being returned to its
/// `Connection`'s collection of cached statements. /// `Connection`'s collection of cached statements.
#[inline]
pub fn discard(mut self) { pub fn discard(mut self) {
self.stmt = None; self.stmt = None;
} }
@ -106,10 +114,12 @@ impl CachedStatement<'_> {
impl StatementCache { impl StatementCache {
/// Create a statement cache. /// Create a statement cache.
#[inline]
pub fn with_capacity(capacity: usize) -> StatementCache { pub fn with_capacity(capacity: usize) -> StatementCache {
StatementCache(RefCell::new(LruCache::new(capacity))) StatementCache(RefCell::new(LruCache::new(capacity)))
} }
#[inline]
fn set_capacity(&self, capacity: usize) { fn set_capacity(&self, capacity: usize) {
self.0.borrow_mut().set_capacity(capacity) self.0.borrow_mut().set_capacity(capacity)
} }
@ -155,6 +165,7 @@ impl StatementCache {
} }
} }
#[inline]
fn flush(&self) { fn flush(&self) {
let mut cache = self.0.borrow_mut(); let mut cache = self.0.borrow_mut();
cache.clear() cache.clear()

View File

@ -15,6 +15,7 @@ unsafe extern "C" fn free_boxed_value<T>(p: *mut c_void) {
impl Connection { impl Connection {
/// `feature = "collation"` Add or modify a collation. /// `feature = "collation"` Add or modify a collation.
#[inline]
pub fn create_collation<'c, C>(&'c self, collation_name: &str, x_compare: C) -> Result<()> pub fn create_collation<'c, C>(&'c self, collation_name: &str, x_compare: C) -> Result<()>
where where
C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c, C: Fn(&str, &str) -> Ordering + Send + UnwindSafe + 'c,
@ -25,6 +26,7 @@ impl Connection {
} }
/// `feature = "collation"` Collation needed callback /// `feature = "collation"` Collation needed callback
#[inline]
pub fn collation_needed( pub fn collation_needed(
&self, &self,
x_coll_needed: fn(&Connection, &str) -> Result<()>, x_coll_needed: fn(&Connection, &str) -> Result<()>,
@ -33,6 +35,7 @@ impl Connection {
} }
/// `feature = "collation"` Remove collation. /// `feature = "collation"` Remove collation.
#[inline]
pub fn remove_collation(&self, collation_name: &str) -> Result<()> { pub fn remove_collation(&self, collation_name: &str) -> Result<()> {
self.db.borrow_mut().remove_collation(collation_name) self.db.borrow_mut().remove_collation(collation_name)
} }
@ -139,6 +142,7 @@ impl InnerConnection {
self.decode_result(r) self.decode_result(r)
} }
#[inline]
fn remove_collation(&mut self, collation_name: &str) -> Result<()> { fn remove_collation(&mut self, collation_name: &str) -> Result<()> {
let c_name = str_to_cstring(collation_name)?; let c_name = str_to_cstring(collation_name)?;
let r = unsafe { let r = unsafe {

View File

@ -11,11 +11,13 @@ pub struct Column<'stmt> {
impl Column<'_> { impl Column<'_> {
/// Returns the name of the column. /// Returns the name of the column.
#[inline]
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
self.name self.name
} }
/// Returns the type of the column (`None` for expression). /// Returns the type of the column (`None` for expression).
#[inline]
pub fn decl_type(&self) -> Option<&str> { pub fn decl_type(&self) -> Option<&str> {
self.decl_type self.decl_type
} }
@ -35,10 +37,12 @@ impl Statement<'_> {
/// Return the number of columns in the result set returned by the prepared /// Return the number of columns in the result set returned by the prepared
/// statement. /// statement.
#[inline]
pub fn column_count(&self) -> usize { pub fn column_count(&self) -> usize {
self.stmt.column_count() self.stmt.column_count()
} }
#[inline]
pub(super) fn column_name_unwrap(&self, col: usize) -> &str { pub(super) fn column_name_unwrap(&self, col: usize) -> &str {
// Just panic if the bounds are wrong for now, we never call this // Just panic if the bounds are wrong for now, we never call this
// without checking first. // without checking first.
@ -54,6 +58,7 @@ impl Statement<'_> {
/// column range for this row. /// column range for this row.
/// ///
/// Panics when column name is not valid UTF-8. /// Panics when column name is not valid UTF-8.
#[inline]
pub fn column_name(&self, col: usize) -> Result<&str> { pub fn column_name(&self, col: usize) -> Result<&str> {
self.stmt self.stmt
.column_name(col) .column_name(col)
@ -72,6 +77,7 @@ impl Statement<'_> {
/// ///
/// Will return an `Error::InvalidColumnName` when there is no column with /// Will return an `Error::InvalidColumnName` when there is no column with
/// the specified `name`. /// the specified `name`.
#[inline]
pub fn column_index(&self, name: &str) -> Result<usize> { pub fn column_index(&self, name: &str) -> Result<usize> {
let bytes = name.as_bytes(); let bytes = name.as_bytes();
let n = self.column_count(); let n = self.column_count();
@ -104,26 +110,31 @@ impl Statement<'_> {
impl<'stmt> Rows<'stmt> { impl<'stmt> Rows<'stmt> {
/// Get all the column names. /// Get all the column names.
#[inline]
pub fn column_names(&self) -> Option<Vec<&str>> { pub fn column_names(&self) -> Option<Vec<&str>> {
self.stmt.map(Statement::column_names) self.stmt.map(Statement::column_names)
} }
/// Return the number of columns. /// Return the number of columns.
#[inline]
pub fn column_count(&self) -> Option<usize> { pub fn column_count(&self) -> Option<usize> {
self.stmt.map(Statement::column_count) self.stmt.map(Statement::column_count)
} }
/// Return the name of the column. /// Return the name of the column.
#[inline]
pub fn column_name(&self, col: usize) -> Option<Result<&str>> { pub fn column_name(&self, col: usize) -> Option<Result<&str>> {
self.stmt.map(|stmt| stmt.column_name(col)) self.stmt.map(|stmt| stmt.column_name(col))
} }
/// Return the index of the column. /// Return the index of the column.
#[inline]
pub fn column_index(&self, name: &str) -> Option<Result<usize>> { pub fn column_index(&self, name: &str) -> Option<Result<usize>> {
self.stmt.map(|stmt| stmt.column_index(name)) self.stmt.map(|stmt| stmt.column_index(name))
} }
/// Returns a slice describing the columns of the Rows. /// Returns a slice describing the columns of the Rows.
#[inline]
#[cfg(feature = "column_decltype")] #[cfg(feature = "column_decltype")]
pub fn columns(&self) -> Option<Vec<Column>> { pub fn columns(&self) -> Option<Vec<Column>> {
self.stmt.map(Statement::columns) self.stmt.map(Statement::columns)
@ -132,26 +143,31 @@ impl<'stmt> Rows<'stmt> {
impl<'stmt> Row<'stmt> { impl<'stmt> Row<'stmt> {
/// Get all the column names of the Row. /// Get all the column names of the Row.
#[inline]
pub fn column_names(&self) -> Vec<&str> { pub fn column_names(&self) -> Vec<&str> {
self.stmt.column_names() self.stmt.column_names()
} }
/// Return the number of columns in the current row. /// Return the number of columns in the current row.
#[inline]
pub fn column_count(&self) -> usize { pub fn column_count(&self) -> usize {
self.stmt.column_count() self.stmt.column_count()
} }
/// Return the name of the column. /// Return the name of the column.
#[inline]
pub fn column_name(&self, col: usize) -> Result<&str> { pub fn column_name(&self, col: usize) -> Result<&str> {
self.stmt.column_name(col) self.stmt.column_name(col)
} }
/// Return the index of the column. /// Return the index of the column.
#[inline]
pub fn column_index(&self, name: &str) -> Result<usize> { pub fn column_index(&self, name: &str) -> Result<usize> {
self.stmt.column_index(name) self.stmt.column_index(name)
} }
/// Returns a slice describing the columns of the Row. /// Returns a slice describing the columns of the Row.
#[inline]
#[cfg(feature = "column_decltype")] #[cfg(feature = "column_decltype")]
pub fn columns(&self) -> Vec<Column> { pub fn columns(&self) -> Vec<Column> {
self.stmt.columns() self.stmt.columns()

View File

@ -74,6 +74,7 @@ impl Connection {
/// whether the QPSG is disabled or enabled /// whether the QPSG is disabled or enabled
/// - SQLITE_DBCONFIG_TRIGGER_EQP: return `false` to indicate /// - SQLITE_DBCONFIG_TRIGGER_EQP: return `false` to indicate
/// output-for-trigger are not disabled or `true` if it is /// output-for-trigger are not disabled or `true` if it is
#[inline]
pub fn db_config(&self, config: DbConfig) -> Result<bool> { pub fn db_config(&self, config: DbConfig) -> Result<bool> {
let c = self.db.borrow(); let c = self.db.borrow();
unsafe { unsafe {
@ -102,6 +103,7 @@ impl Connection {
/// enable QPSG /// enable QPSG
/// - SQLITE_DBCONFIG_TRIGGER_EQP: `false` to disable output for trigger /// - SQLITE_DBCONFIG_TRIGGER_EQP: `false` to disable output for trigger
/// programs, `true` to enable it /// programs, `true` to enable it
#[inline]
pub fn set_db_config(&self, config: DbConfig, new_val: bool) -> Result<bool> { pub fn set_db_config(&self, config: DbConfig, new_val: bool) -> Result<bool> {
let c = self.db.borrow_mut(); let c = self.db.borrow_mut();
unsafe { unsafe {

View File

@ -12,6 +12,10 @@ use crate::types::{ToSqlOutput, ValueRef};
#[cfg(feature = "array")] #[cfg(feature = "array")]
use crate::vtab::array::{free_array, ARRAY_TYPE}; use crate::vtab::array::{free_array, ARRAY_TYPE};
// This function is inline despite it's size because what's in the ToSqlOutput
// is often known to the compiler, and thus const prop/DCE can substantially
// simplify the function.
#[inline]
pub(super) unsafe fn set_result(ctx: *mut sqlite3_context, result: &ToSqlOutput<'_>) { pub(super) unsafe fn set_result(ctx: *mut sqlite3_context, result: &ToSqlOutput<'_>) {
let value = match *result { let value = match *result {
ToSqlOutput::Borrowed(v) => v, ToSqlOutput::Borrowed(v) => v,

View File

@ -166,12 +166,14 @@ impl PartialEq for Error {
} }
impl From<str::Utf8Error> for Error { impl From<str::Utf8Error> for Error {
#[cold]
fn from(err: str::Utf8Error) -> Error { fn from(err: str::Utf8Error) -> Error {
Error::Utf8Error(err) Error::Utf8Error(err)
} }
} }
impl From<::std::ffi::NulError> for Error { impl From<::std::ffi::NulError> for Error {
#[cold]
fn from(err: ::std::ffi::NulError) -> Error { fn from(err: ::std::ffi::NulError) -> Error {
Error::NulError(err) Error::NulError(err)
} }
@ -182,6 +184,7 @@ const UNKNOWN_COLUMN: usize = std::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`.
impl From<FromSqlError> for Error { impl From<FromSqlError> for Error {
#[cold]
fn from(err: FromSqlError) -> Error { fn from(err: FromSqlError) -> Error {
// The error type requires index and type fields, but they aren't known in this // The error type requires index and type fields, but they aren't known in this
// context. // context.
@ -327,10 +330,12 @@ impl error::Error for Error {
// These are public but not re-exported by lib.rs, so only visible within crate. // These are public but not re-exported by lib.rs, so only visible within crate.
#[cold]
pub fn error_from_sqlite_code(code: c_int, message: Option<String>) -> Error { pub fn error_from_sqlite_code(code: c_int, message: Option<String>) -> Error {
Error::SqliteFailure(ffi::Error::new(code), message) Error::SqliteFailure(ffi::Error::new(code), message)
} }
#[cold]
pub unsafe fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error { pub unsafe fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error {
let message = if db.is_null() { let message = if db.is_null() {
None None

View File

@ -111,11 +111,13 @@ pub struct Context<'a> {
impl Context<'_> { impl Context<'_> {
/// Returns the number of arguments to the function. /// Returns the number of arguments to the function.
#[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.args.len() self.args.len()
} }
/// Returns `true` when there is no argument. /// Returns `true` when there is no argument.
#[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.args.is_empty() self.args.is_empty()
} }
@ -155,6 +157,7 @@ impl Context<'_> {
/// # Failure /// # Failure
/// ///
/// Will panic if `idx` is greater than or equal to `self.len()`. /// Will panic if `idx` is greater than or equal to `self.len()`.
#[inline]
pub fn get_raw(&self, idx: usize) -> ValueRef<'_> { pub fn get_raw(&self, idx: usize) -> ValueRef<'_> {
let arg = self.args[idx]; let arg = self.args[idx];
unsafe { ValueRef::from_value(arg) } unsafe { ValueRef::from_value(arg) }
@ -290,6 +293,7 @@ bitflags::bitflags! {
} }
impl Default for FunctionFlags { impl Default for FunctionFlags {
#[inline]
fn default() -> FunctionFlags { fn default() -> FunctionFlags {
FunctionFlags::SQLITE_UTF8 FunctionFlags::SQLITE_UTF8
} }
@ -332,6 +336,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return Err if the function could not be attached to the connection. /// Will return Err if the function could not be attached to the connection.
#[inline]
pub fn create_scalar_function<'c, F, T>( pub fn create_scalar_function<'c, F, T>(
&'c self, &'c self,
fn_name: &str, fn_name: &str,
@ -354,6 +359,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return Err if the function could not be attached to the connection. /// Will return Err if the function could not be attached to the connection.
#[inline]
pub fn create_aggregate_function<A, D, T>( pub fn create_aggregate_function<A, D, T>(
&self, &self,
fn_name: &str, fn_name: &str,
@ -377,6 +383,7 @@ impl Connection {
/// See https://sqlite.org/windowfunctions.html#udfwinfunc for more /// See https://sqlite.org/windowfunctions.html#udfwinfunc for more
/// information. /// information.
#[cfg(feature = "window")] #[cfg(feature = "window")]
#[inline]
pub fn create_window_function<A, W, T>( pub fn create_window_function<A, W, T>(
&self, &self,
fn_name: &str, fn_name: &str,
@ -403,6 +410,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return Err if the function could not be removed. /// Will return Err if the function could not be removed.
#[inline]
pub fn remove_function(&self, fn_name: &str, n_arg: c_int) -> Result<()> { pub fn remove_function(&self, fn_name: &str, n_arg: c_int) -> Result<()> {
self.db.borrow_mut().remove_function(fn_name, n_arg) self.db.borrow_mut().remove_function(fn_name, n_arg)
} }

View File

@ -25,6 +25,7 @@ pub enum Action {
} }
impl From<i32> for Action { impl From<i32> for Action {
#[inline]
fn from(code: i32) -> Action { fn from(code: i32) -> Action {
match code { match code {
ffi::SQLITE_DELETE => Action::SQLITE_DELETE, ffi::SQLITE_DELETE => Action::SQLITE_DELETE,
@ -40,6 +41,7 @@ impl Connection {
/// a transaction is committed. /// a transaction is committed.
/// ///
/// The callback returns `true` to rollback. /// The callback returns `true` to rollback.
#[inline]
pub fn commit_hook<'c, F>(&'c self, hook: Option<F>) pub fn commit_hook<'c, F>(&'c self, hook: Option<F>)
where where
F: FnMut() -> bool + Send + 'c, F: FnMut() -> bool + Send + 'c,
@ -51,6 +53,7 @@ impl Connection {
/// a transaction is committed. /// a transaction is committed.
/// ///
/// The callback returns `true` to rollback. /// The callback returns `true` to rollback.
#[inline]
pub fn rollback_hook<'c, F>(&'c self, hook: Option<F>) pub fn rollback_hook<'c, F>(&'c self, hook: Option<F>)
where where
F: FnMut() + Send + 'c, F: FnMut() + Send + 'c,
@ -68,6 +71,7 @@ impl Connection {
/// - the name of the database ("main", "temp", ...), /// - the name of the database ("main", "temp", ...),
/// - the name of the table that is updated, /// - the name of the table that is updated,
/// - the ROWID of the row that is updated. /// - the ROWID of the row that is updated.
#[inline]
pub fn update_hook<'c, F>(&'c self, hook: Option<F>) pub fn update_hook<'c, F>(&'c self, hook: Option<F>)
where where
F: FnMut(Action, &str, &str, i64) + Send + 'c, F: FnMut(Action, &str, &str, i64) + Send + 'c,
@ -92,6 +96,7 @@ impl Connection {
} }
impl InnerConnection { impl InnerConnection {
#[inline]
pub fn remove_hooks(&mut self) { pub fn remove_hooks(&mut self) {
self.update_hook(None::<fn(Action, &str, &str, i64)>); self.update_hook(None::<fn(Action, &str, &str, i64)>);
self.commit_hook(None::<fn() -> bool>); self.commit_hook(None::<fn() -> bool>);

View File

@ -38,6 +38,7 @@ pub struct InnerConnection {
impl InnerConnection { impl InnerConnection {
#[allow(clippy::mutex_atomic)] #[allow(clippy::mutex_atomic)]
#[inline]
pub unsafe fn new(db: *mut ffi::sqlite3, owned: bool) -> InnerConnection { pub unsafe fn new(db: *mut ffi::sqlite3, owned: bool) -> InnerConnection {
InnerConnection { InnerConnection {
db, db,
@ -125,14 +126,17 @@ impl InnerConnection {
} }
} }
#[inline]
pub fn db(&self) -> *mut ffi::sqlite3 { pub fn db(&self) -> *mut ffi::sqlite3 {
self.db self.db
} }
#[inline]
pub fn decode_result(&mut self, code: c_int) -> Result<()> { pub fn decode_result(&mut self, code: c_int) -> Result<()> {
unsafe { InnerConnection::decode_result_raw(self.db(), code) } unsafe { InnerConnection::decode_result_raw(self.db(), code) }
} }
#[inline]
unsafe fn decode_result_raw(db: *mut ffi::sqlite3, code: c_int) -> Result<()> { unsafe fn decode_result_raw(db: *mut ffi::sqlite3, code: c_int) -> Result<()> {
if code == ffi::SQLITE_OK { if code == ffi::SQLITE_OK {
Ok(()) Ok(())
@ -169,12 +173,14 @@ impl InnerConnection {
} }
} }
#[inline]
pub fn get_interrupt_handle(&self) -> InterruptHandle { pub fn get_interrupt_handle(&self) -> InterruptHandle {
InterruptHandle { InterruptHandle {
db_lock: Arc::clone(&self.interrupt_lock), db_lock: Arc::clone(&self.interrupt_lock),
} }
} }
#[inline]
#[cfg(feature = "load_extension")] #[cfg(feature = "load_extension")]
pub fn enable_load_extension(&mut self, onoff: c_int) -> Result<()> { pub fn enable_load_extension(&mut self, onoff: c_int) -> Result<()> {
let r = unsafe { ffi::sqlite3_enable_load_extension(self.db, onoff) }; let r = unsafe { ffi::sqlite3_enable_load_extension(self.db, onoff) };
@ -207,6 +213,7 @@ impl InnerConnection {
} }
} }
#[inline]
pub fn last_insert_rowid(&self) -> i64 { pub fn last_insert_rowid(&self) -> i64 {
unsafe { ffi::sqlite3_last_insert_rowid(self.db()) } unsafe { ffi::sqlite3_last_insert_rowid(self.db()) }
} }
@ -266,10 +273,12 @@ impl InnerConnection {
})) }))
} }
#[inline]
pub fn changes(&mut self) -> usize { pub fn changes(&mut self) -> usize {
unsafe { ffi::sqlite3_changes(self.db()) as usize } unsafe { ffi::sqlite3_changes(self.db()) as usize }
} }
#[inline]
pub fn is_autocommit(&self) -> bool { pub fn is_autocommit(&self) -> bool {
unsafe { ffi::sqlite3_get_autocommit(self.db()) != 0 } unsafe { ffi::sqlite3_get_autocommit(self.db()) != 0 }
} }
@ -290,11 +299,13 @@ impl InnerConnection {
} }
#[cfg(not(feature = "hooks"))] #[cfg(not(feature = "hooks"))]
#[inline]
fn remove_hooks(&mut self) {} fn remove_hooks(&mut self) {}
} }
impl Drop for InnerConnection { impl Drop for InnerConnection {
#[allow(unused_must_use)] #[allow(unused_must_use)]
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
use std::thread::panicking; use std::thread::panicking;

View File

@ -282,7 +282,7 @@ fn path_to_cstring(p: &Path) -> Result<CString> {
} }
/// Name for a database within a SQLite connection. /// Name for a database within a SQLite connection.
#[derive(Copy, Clone)] #[derive(Copy, Clone, Debug)]
pub enum DatabaseName<'a> { pub enum DatabaseName<'a> {
/// The main database. /// The main database.
Main, Main,
@ -294,6 +294,12 @@ pub enum DatabaseName<'a> {
Attached(&'a str), Attached(&'a str),
} }
/// Shorthand for [`DatabaseName::Main`].
pub const MAIN_DB: DatabaseName<'static> = DatabaseName::Main;
/// Shorthand for [`DatabaseName::Temp`].
pub const TEMP_DB: DatabaseName<'static> = DatabaseName::Temp;
// Currently DatabaseName is only used by the backup and blob mods, so hide // Currently DatabaseName is only used by the backup and blob mods, so hide
// this (private) impl to avoid dead code warnings. // this (private) impl to avoid dead code warnings.
#[cfg(any( #[cfg(any(
@ -303,6 +309,7 @@ pub enum DatabaseName<'a> {
feature = "modern_sqlite" feature = "modern_sqlite"
))] ))]
impl DatabaseName<'_> { impl DatabaseName<'_> {
#[inline]
fn to_cstring(&self) -> Result<util::SmallCString> { fn to_cstring(&self) -> Result<util::SmallCString> {
use self::DatabaseName::{Attached, Main, Temp}; use self::DatabaseName::{Attached, Main, Temp};
match *self { match *self {
@ -323,6 +330,7 @@ pub struct Connection {
unsafe impl Send for Connection {} unsafe impl Send for Connection {}
impl Drop for Connection { impl Drop for Connection {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.flush_prepared_statement_cache(); self.flush_prepared_statement_cache();
} }
@ -350,6 +358,7 @@ impl Connection {
/// ///
/// Will return `Err` if `path` cannot be converted to a C-compatible /// Will return `Err` if `path` cannot be converted to a C-compatible
/// string or if the underlying SQLite open call fails. /// string or if the underlying SQLite open call fails.
#[inline]
pub fn open<P: AsRef<Path>>(path: P) -> Result<Connection> { pub fn open<P: AsRef<Path>>(path: P) -> Result<Connection> {
let flags = OpenFlags::default(); let flags = OpenFlags::default();
Connection::open_with_flags(path, flags) Connection::open_with_flags(path, flags)
@ -360,6 +369,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite open call fails. /// Will return `Err` if the underlying SQLite open call fails.
#[inline]
pub fn open_in_memory() -> Result<Connection> { pub fn open_in_memory() -> Result<Connection> {
let flags = OpenFlags::default(); let flags = OpenFlags::default();
Connection::open_in_memory_with_flags(flags) Connection::open_in_memory_with_flags(flags)
@ -374,6 +384,7 @@ impl Connection {
/// ///
/// Will return `Err` if `path` cannot be converted to a C-compatible /// Will return `Err` if `path` cannot be converted to a C-compatible
/// string or if the underlying SQLite open call fails. /// string or if the underlying SQLite open call fails.
#[inline]
pub fn open_with_flags<P: AsRef<Path>>(path: P, flags: OpenFlags) -> Result<Connection> { pub fn open_with_flags<P: AsRef<Path>>(path: P, flags: OpenFlags) -> Result<Connection> {
let c_path = path_to_cstring(path.as_ref())?; let c_path = path_to_cstring(path.as_ref())?;
InnerConnection::open_with_flags(&c_path, flags, None).map(|db| Connection { InnerConnection::open_with_flags(&c_path, flags, None).map(|db| Connection {
@ -393,6 +404,7 @@ impl Connection {
/// ///
/// Will return `Err` if either `path` or `vfs` cannot be converted to a /// Will return `Err` if either `path` or `vfs` cannot be converted to a
/// C-compatible string or if the underlying SQLite open call fails. /// C-compatible string or if the underlying SQLite open call fails.
#[inline]
pub fn open_with_flags_and_vfs<P: AsRef<Path>>( pub fn open_with_flags_and_vfs<P: AsRef<Path>>(
path: P, path: P,
flags: OpenFlags, flags: OpenFlags,
@ -415,6 +427,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite open call fails. /// Will return `Err` if the underlying SQLite open call fails.
#[inline]
pub fn open_in_memory_with_flags(flags: OpenFlags) -> Result<Connection> { pub fn open_in_memory_with_flags(flags: OpenFlags) -> Result<Connection> {
Connection::open_with_flags(":memory:", flags) Connection::open_with_flags(":memory:", flags)
} }
@ -429,6 +442,7 @@ impl Connection {
/// ///
/// Will return `Err` if vfs` cannot be converted to a C-compatible /// Will return `Err` if vfs` cannot be converted to a C-compatible
/// string or if the underlying SQLite open call fails. /// string or if the underlying SQLite open call fails.
#[inline]
pub fn open_in_memory_with_flags_and_vfs(flags: OpenFlags, vfs: &str) -> Result<Connection> { pub fn open_in_memory_with_flags_and_vfs(flags: OpenFlags, vfs: &str) -> Result<Connection> {
Connection::open_with_flags_and_vfs(":memory:", flags, vfs) Connection::open_with_flags_and_vfs(":memory:", flags, vfs)
} }
@ -518,6 +532,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.
#[inline]
pub fn execute<P: Params>(&self, sql: &str, params: P) -> Result<usize> { pub fn execute<P: Params>(&self, sql: &str, params: P) -> Result<usize> {
self.prepare(sql) self.prepare(sql)
.and_then(|mut stmt| stmt.check_no_tail().and_then(|_| stmt.execute(params))) .and_then(|mut stmt| stmt.check_no_tail().and_then(|_| stmt.execute(params)))
@ -547,6 +562,7 @@ impl Connection {
/// ///
/// Uses [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html) under /// Uses [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html) under
/// the hood. /// the hood.
#[inline]
pub fn last_insert_rowid(&self) -> i64 { pub fn last_insert_rowid(&self) -> i64 {
self.db.borrow_mut().last_insert_rowid() self.db.borrow_mut().last_insert_rowid()
} }
@ -578,6 +594,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.
#[inline]
pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<T> pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<T>
where where
P: Params, P: Params,
@ -635,6 +652,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.
#[inline]
pub fn query_row_and_then<T, E, P, F>(&self, sql: &str, params: P, f: F) -> Result<T, E> pub fn query_row_and_then<T, E, P, F>(&self, sql: &str, params: P, f: F) -> Result<T, E>
where where
P: Params, P: Params,
@ -666,6 +684,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.
#[inline]
pub fn prepare(&self, sql: &str) -> Result<Statement<'_>> { pub fn prepare(&self, sql: &str) -> Result<Statement<'_>> {
self.db.borrow_mut().prepare(self, sql) self.db.borrow_mut().prepare(self, sql)
} }
@ -679,6 +698,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[inline]
pub fn close(self) -> Result<(), (Connection, Error)> { pub fn close(self) -> Result<(), (Connection, Error)> {
self.flush_prepared_statement_cache(); self.flush_prepared_statement_cache();
let r = self.db.borrow_mut().close(); let r = self.db.borrow_mut().close();
@ -704,6 +724,7 @@ impl Connection {
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[cfg(feature = "load_extension")] #[cfg(feature = "load_extension")]
#[inline]
pub fn load_extension_enable(&self) -> Result<()> { pub fn load_extension_enable(&self) -> Result<()> {
self.db.borrow_mut().enable_load_extension(1) self.db.borrow_mut().enable_load_extension(1)
} }
@ -716,6 +737,7 @@ impl Connection {
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[cfg(feature = "load_extension")] #[cfg(feature = "load_extension")]
#[inline]
pub fn load_extension_disable(&self) -> Result<()> { pub fn load_extension_disable(&self) -> Result<()> {
self.db.borrow_mut().enable_load_extension(0) self.db.borrow_mut().enable_load_extension(0)
} }
@ -744,6 +766,7 @@ impl Connection {
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[cfg(feature = "load_extension")] #[cfg(feature = "load_extension")]
#[inline]
pub fn load_extension<P: AsRef<Path>>( pub fn load_extension<P: AsRef<Path>>(
&self, &self,
dylib_path: P, dylib_path: P,
@ -767,6 +790,7 @@ impl Connection {
/// This function is unsafe because it gives you raw access /// This function is unsafe because it gives you raw access
/// to the SQLite connection, and what you do with it could impact the /// to the SQLite connection, and what you do with it could impact the
/// safety of this `Connection`. /// safety of this `Connection`.
#[inline]
pub unsafe fn handle(&self) -> *mut ffi::sqlite3 { pub unsafe fn handle(&self) -> *mut ffi::sqlite3 {
self.db.borrow().db() self.db.borrow().db()
} }
@ -779,6 +803,7 @@ impl Connection {
/// # Safety /// # Safety
/// ///
/// This function is unsafe because improper use may impact the Connection. /// This function is unsafe because improper use may impact the Connection.
#[inline]
pub unsafe fn from_handle(db: *mut ffi::sqlite3) -> Result<Connection> { pub unsafe fn from_handle(db: *mut ffi::sqlite3) -> Result<Connection> {
let db_path = db_filename(db); let db_path = db_filename(db);
let db = InnerConnection::new(db, false); let db = InnerConnection::new(db, false);
@ -791,10 +816,12 @@ impl Connection {
/// Get access to a handle that can be used to interrupt long running /// Get access to a handle that can be used to interrupt long running
/// queries from another thread. /// queries from another thread.
#[inline]
pub fn get_interrupt_handle(&self) -> InterruptHandle { pub fn get_interrupt_handle(&self) -> InterruptHandle {
self.db.borrow().get_interrupt_handle() self.db.borrow().get_interrupt_handle()
} }
#[inline]
fn decode_result(&self, code: c_int) -> Result<()> { fn decode_result(&self, code: c_int) -> Result<()> {
self.db.borrow_mut().decode_result(code) self.db.borrow_mut().decode_result(code)
} }
@ -802,17 +829,20 @@ impl Connection {
/// Return the number of rows modified, inserted or deleted by the most /// Return the number of rows modified, inserted or deleted by the most
/// recently completed INSERT, UPDATE or DELETE statement on the database /// recently completed INSERT, UPDATE or DELETE statement on the database
/// connection. /// connection.
#[inline]
fn changes(&self) -> usize { fn changes(&self) -> usize {
self.db.borrow_mut().changes() self.db.borrow_mut().changes()
} }
/// Test for auto-commit mode. /// Test for auto-commit mode.
/// Autocommit mode is on by default. /// Autocommit mode is on by default.
#[inline]
pub fn is_autocommit(&self) -> bool { pub fn is_autocommit(&self) -> bool {
self.db.borrow().is_autocommit() self.db.borrow().is_autocommit()
} }
/// Determine if all associated prepared statements have been reset. /// Determine if all associated prepared statements have been reset.
#[inline]
#[cfg(feature = "modern_sqlite")] // 3.8.6 #[cfg(feature = "modern_sqlite")] // 3.8.6
pub fn is_busy(&self) -> bool { pub fn is_busy(&self) -> bool {
self.db.borrow().is_busy() self.db.borrow().is_busy()

View File

@ -9,6 +9,7 @@ use crate::Connection;
impl Connection { impl Connection {
/// `feature = "limits"` Returns the current value of a limit. /// `feature = "limits"` Returns the current value of a limit.
#[inline]
pub fn limit(&self, limit: Limit) -> i32 { pub fn limit(&self, limit: Limit) -> i32 {
let c = self.db.borrow(); let c = self.db.borrow();
unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, -1) } unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, -1) }
@ -16,6 +17,7 @@ impl Connection {
/// `feature = "limits"` Changes the limit to `new_val`, returning the prior /// `feature = "limits"` Changes the limit to `new_val`, returning the prior
/// value of the limit. /// value of the limit.
#[inline]
pub fn set_limit(&self, limit: Limit, new_val: i32) -> i32 { pub fn set_limit(&self, limit: Limit, new_val: i32) -> i32 {
let c = self.db.borrow_mut(); let c = self.db.borrow_mut();
unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, new_val) } unsafe { ffi::sqlite3_limit(c.db(), limit as c_int, new_val) }

View File

@ -22,6 +22,7 @@ impl LoadExtensionGuard<'_> {
/// 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.
#[inline]
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 })
@ -30,6 +31,7 @@ impl LoadExtensionGuard<'_> {
#[allow(unused_must_use)] #[allow(unused_must_use)]
impl Drop for LoadExtensionGuard<'_> { impl Drop for LoadExtensionGuard<'_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.conn.load_extension_disable(); self.conn.load_extension_disable();
} }

View File

@ -198,6 +198,8 @@ impl Params for &[(&str, &dyn ToSql)] {
macro_rules! impl_for_array_ref { macro_rules! impl_for_array_ref {
($($N:literal)+) => {$( ($($N:literal)+) => {$(
// These are already generic, and theres a shitload of them, so lets
// avoid the compile time hit from making them all inline for now.
impl<T: ToSql + ?Sized> Sealed for &[&T; $N] {} impl<T: ToSql + ?Sized> Sealed for &[&T; $N] {}
impl<T: ToSql + ?Sized> Params for &[&T; $N] { impl<T: ToSql + ?Sized> Params for &[&T; $N] {
fn bind_in(self, stmt: &mut Statement<'_>) -> Result<()> { fn bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {

View File

@ -29,6 +29,7 @@ pub struct RawStatement {
} }
impl RawStatement { impl RawStatement {
#[inline]
pub unsafe fn new(stmt: *mut ffi::sqlite3_stmt, tail: usize) -> RawStatement { pub unsafe fn new(stmt: *mut ffi::sqlite3_stmt, tail: usize) -> RawStatement {
RawStatement { RawStatement {
ptr: stmt, ptr: stmt,
@ -38,31 +39,38 @@ impl RawStatement {
} }
} }
#[inline]
pub fn is_null(&self) -> bool { pub fn is_null(&self) -> bool {
self.ptr.is_null() self.ptr.is_null()
} }
#[inline]
pub(crate) fn set_statement_cache_key(&mut self, p: impl Into<Arc<str>>) { pub(crate) fn set_statement_cache_key(&mut self, p: impl Into<Arc<str>>) {
self.statement_cache_key = Some(p.into()); self.statement_cache_key = Some(p.into());
} }
#[inline]
pub(crate) fn statement_cache_key(&self) -> Option<Arc<str>> { pub(crate) fn statement_cache_key(&self) -> Option<Arc<str>> {
self.statement_cache_key.clone() self.statement_cache_key.clone()
} }
#[inline]
pub unsafe fn ptr(&self) -> *mut ffi::sqlite3_stmt { pub unsafe fn ptr(&self) -> *mut ffi::sqlite3_stmt {
self.ptr self.ptr
} }
#[inline]
pub fn column_count(&self) -> usize { pub fn column_count(&self) -> usize {
// Note: Can't cache this as it changes if the schema is altered. // Note: Can't cache this as it changes if the schema is altered.
unsafe { ffi::sqlite3_column_count(self.ptr) as usize } unsafe { ffi::sqlite3_column_count(self.ptr) as usize }
} }
#[inline]
pub fn column_type(&self, idx: usize) -> c_int { pub fn column_type(&self, idx: usize) -> c_int {
unsafe { ffi::sqlite3_column_type(self.ptr, idx as c_int) } unsafe { ffi::sqlite3_column_type(self.ptr, idx as c_int) }
} }
#[inline]
#[cfg(feature = "column_decltype")] #[cfg(feature = "column_decltype")]
pub fn column_decltype(&self, idx: usize) -> Option<&CStr> { pub fn column_decltype(&self, idx: usize) -> Option<&CStr> {
unsafe { unsafe {
@ -75,6 +83,7 @@ impl RawStatement {
} }
} }
#[inline]
pub fn column_name(&self, idx: usize) -> Option<&CStr> { pub fn column_name(&self, idx: usize) -> Option<&CStr> {
let idx = idx as c_int; let idx = idx as c_int;
if idx < 0 || idx >= self.column_count() as c_int { if idx < 0 || idx >= self.column_count() as c_int {
@ -92,6 +101,7 @@ impl RawStatement {
} }
} }
#[cfg_attr(not(feature = "unlock_notify"), inline)]
pub fn step(&self) -> c_int { pub fn step(&self) -> c_int {
if cfg!(feature = "unlock_notify") { if cfg!(feature = "unlock_notify") {
let db = unsafe { ffi::sqlite3_db_handle(self.ptr) }; let db = unsafe { ffi::sqlite3_db_handle(self.ptr) };
@ -113,14 +123,17 @@ impl RawStatement {
} }
} }
#[inline]
pub fn reset(&self) -> c_int { pub fn reset(&self) -> c_int {
unsafe { ffi::sqlite3_reset(self.ptr) } unsafe { ffi::sqlite3_reset(self.ptr) }
} }
#[inline]
pub fn bind_parameter_count(&self) -> usize { pub fn bind_parameter_count(&self) -> usize {
unsafe { ffi::sqlite3_bind_parameter_count(self.ptr) as usize } unsafe { ffi::sqlite3_bind_parameter_count(self.ptr) as usize }
} }
#[inline]
pub fn bind_parameter_index(&self, name: &str) -> Option<usize> { pub fn bind_parameter_index(&self, name: &str) -> Option<usize> {
self.cache.get_or_insert_with(name, |param_cstr| { self.cache.get_or_insert_with(name, |param_cstr| {
let r = unsafe { ffi::sqlite3_bind_parameter_index(self.ptr, param_cstr.as_ptr()) }; let r = unsafe { ffi::sqlite3_bind_parameter_index(self.ptr, param_cstr.as_ptr()) };
@ -131,10 +144,12 @@ impl RawStatement {
}) })
} }
#[inline]
pub fn clear_bindings(&self) -> c_int { pub fn clear_bindings(&self) -> c_int {
unsafe { ffi::sqlite3_clear_bindings(self.ptr) } unsafe { ffi::sqlite3_clear_bindings(self.ptr) }
} }
#[inline]
pub fn sql(&self) -> Option<&CStr> { pub fn sql(&self) -> Option<&CStr> {
if self.ptr.is_null() { if self.ptr.is_null() {
None None
@ -143,36 +158,43 @@ impl RawStatement {
} }
} }
#[inline]
pub fn finalize(mut self) -> c_int { pub fn finalize(mut self) -> c_int {
self.finalize_() self.finalize_()
} }
#[inline]
fn finalize_(&mut self) -> c_int { fn finalize_(&mut self) -> c_int {
let r = unsafe { ffi::sqlite3_finalize(self.ptr) }; let r = unsafe { ffi::sqlite3_finalize(self.ptr) };
self.ptr = ptr::null_mut(); self.ptr = ptr::null_mut();
r r
} }
#[inline]
#[cfg(all(feature = "extra_check", feature = "modern_sqlite"))] // 3.7.4 #[cfg(all(feature = "extra_check", feature = "modern_sqlite"))] // 3.7.4
pub fn readonly(&self) -> bool { pub fn readonly(&self) -> bool {
unsafe { ffi::sqlite3_stmt_readonly(self.ptr) != 0 } unsafe { ffi::sqlite3_stmt_readonly(self.ptr) != 0 }
} }
#[inline]
#[cfg(feature = "modern_sqlite")] // 3.14.0 #[cfg(feature = "modern_sqlite")] // 3.14.0
pub(crate) fn expanded_sql(&self) -> Option<SqliteMallocString> { pub(crate) fn expanded_sql(&self) -> Option<SqliteMallocString> {
unsafe { SqliteMallocString::from_raw(ffi::sqlite3_expanded_sql(self.ptr)) } unsafe { SqliteMallocString::from_raw(ffi::sqlite3_expanded_sql(self.ptr)) }
} }
#[inline]
pub fn get_status(&self, status: StatementStatus, reset: bool) -> i32 { pub fn get_status(&self, status: StatementStatus, reset: bool) -> i32 {
assert!(!self.ptr.is_null()); assert!(!self.ptr.is_null());
unsafe { ffi::sqlite3_stmt_status(self.ptr, status as i32, reset as i32) } unsafe { ffi::sqlite3_stmt_status(self.ptr, status as i32, reset as i32) }
} }
#[inline]
#[cfg(feature = "extra_check")] #[cfg(feature = "extra_check")]
pub fn has_tail(&self) -> bool { pub fn has_tail(&self) -> bool {
self.tail != 0 self.tail != 0
} }
#[inline]
pub fn tail(&self) -> usize { pub fn tail(&self) -> usize {
self.tail self.tail
} }

View File

@ -13,6 +13,7 @@ pub struct Rows<'stmt> {
} }
impl<'stmt> Rows<'stmt> { impl<'stmt> Rows<'stmt> {
#[inline]
fn reset(&mut self) { fn reset(&mut self) {
if let Some(stmt) = self.stmt.take() { if let Some(stmt) = self.stmt.take() {
stmt.reset(); stmt.reset();
@ -31,6 +32,7 @@ impl<'stmt> Rows<'stmt> {
/// consider using `query_map` or `query_and_then` instead, which /// consider using `query_map` or `query_and_then` instead, which
/// return types that implement `Iterator`. /// return types that implement `Iterator`.
#[allow(clippy::should_implement_trait)] // cannot implement Iterator #[allow(clippy::should_implement_trait)] // cannot implement Iterator
#[inline]
pub fn next(&mut self) -> Result<Option<&Row<'stmt>>> { pub fn next(&mut self) -> Result<Option<&Row<'stmt>>> {
self.advance()?; self.advance()?;
Ok((*self).get()) Ok((*self).get())
@ -47,6 +49,7 @@ impl<'stmt> Rows<'stmt> {
/// } /// }
/// ``` /// ```
// FIXME Hide FallibleStreamingIterator::map // FIXME Hide FallibleStreamingIterator::map
#[inline]
pub fn map<F, B>(self, f: F) -> Map<'stmt, F> pub fn map<F, B>(self, f: F) -> Map<'stmt, F>
where where
F: FnMut(&Row<'_>) -> Result<B>, F: FnMut(&Row<'_>) -> Result<B>,
@ -56,6 +59,7 @@ impl<'stmt> Rows<'stmt> {
/// Map over this `Rows`, converting it to a [`MappedRows`], which /// Map over this `Rows`, converting it to a [`MappedRows`], which
/// implements `Iterator`. /// implements `Iterator`.
#[inline]
pub fn mapped<F, B>(self, f: F) -> MappedRows<'stmt, F> pub fn mapped<F, B>(self, f: F) -> MappedRows<'stmt, F>
where where
F: FnMut(&Row<'_>) -> Result<B>, F: FnMut(&Row<'_>) -> Result<B>,
@ -66,6 +70,7 @@ impl<'stmt> Rows<'stmt> {
/// Map over this `Rows` with a fallible function, converting it to a /// Map over this `Rows` with a fallible function, converting it to a
/// [`AndThenRows`], which implements `Iterator` (instead of /// [`AndThenRows`], which implements `Iterator` (instead of
/// `FallibleStreamingIterator`). /// `FallibleStreamingIterator`).
#[inline]
pub fn and_then<F, T, E>(self, f: F) -> AndThenRows<'stmt, F> pub fn and_then<F, T, E>(self, f: F) -> AndThenRows<'stmt, F>
where where
F: FnMut(&Row<'_>) -> Result<T, E>, F: FnMut(&Row<'_>) -> Result<T, E>,
@ -75,6 +80,7 @@ impl<'stmt> Rows<'stmt> {
} }
impl<'stmt> Rows<'stmt> { impl<'stmt> Rows<'stmt> {
#[inline]
pub(crate) fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> { pub(crate) fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> {
Rows { Rows {
stmt: Some(stmt), stmt: Some(stmt),
@ -82,6 +88,7 @@ impl<'stmt> Rows<'stmt> {
} }
} }
#[inline]
pub(crate) fn get_expected_row(&mut self) -> Result<&Row<'stmt>> { pub(crate) fn get_expected_row(&mut self) -> Result<&Row<'stmt>> {
match self.next()? { match self.next()? {
Some(row) => Ok(row), Some(row) => Ok(row),
@ -91,6 +98,7 @@ impl<'stmt> Rows<'stmt> {
} }
impl Drop for Rows<'_> { impl Drop for Rows<'_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.reset(); self.reset();
} }
@ -110,6 +118,7 @@ where
type Error = Error; type Error = Error;
type Item = B; type Item = B;
#[inline]
fn next(&mut self) -> Result<Option<B>> { fn next(&mut self) -> Result<Option<B>> {
match self.rows.next()? { match self.rows.next()? {
Some(v) => Ok(Some((self.f)(v)?)), Some(v) => Ok(Some((self.f)(v)?)),
@ -127,21 +136,13 @@ pub struct MappedRows<'stmt, F> {
map: F, map: F,
} }
impl<'stmt, T, F> MappedRows<'stmt, F>
where
F: FnMut(&Row<'_>) -> Result<T>,
{
pub(crate) fn new(rows: Rows<'stmt>, f: F) -> MappedRows<'stmt, F> {
MappedRows { rows, map: f }
}
}
impl<T, F> Iterator for MappedRows<'_, F> impl<T, F> Iterator for MappedRows<'_, F>
where where
F: FnMut(&Row<'_>) -> Result<T>, F: FnMut(&Row<'_>) -> Result<T>,
{ {
type Item = Result<T>; type Item = Result<T>;
#[inline]
fn next(&mut self) -> Option<Result<T>> { fn next(&mut self) -> Option<Result<T>> {
let map = &mut self.map; let map = &mut self.map;
self.rows self.rows
@ -159,15 +160,6 @@ pub struct AndThenRows<'stmt, F> {
map: F, map: F,
} }
impl<'stmt, T, E, F> AndThenRows<'stmt, F>
where
F: FnMut(&Row<'_>) -> Result<T, E>,
{
pub(crate) fn new(rows: Rows<'stmt>, f: F) -> AndThenRows<'stmt, F> {
AndThenRows { rows, map: f }
}
}
impl<T, E, F> Iterator for AndThenRows<'_, F> impl<T, E, F> Iterator for AndThenRows<'_, F>
where where
E: convert::From<Error>, E: convert::From<Error>,
@ -175,6 +167,7 @@ where
{ {
type Item = Result<T, E>; type Item = Result<T, E>;
#[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let map = &mut self.map; let map = &mut self.map;
self.rows self.rows
@ -206,6 +199,7 @@ impl<'stmt> FallibleStreamingIterator for Rows<'stmt> {
type Error = Error; type Error = Error;
type Item = Row<'stmt>; type Item = Row<'stmt>;
#[inline]
fn advance(&mut self) -> Result<()> { fn advance(&mut self) -> Result<()> {
match self.stmt { match self.stmt {
Some(ref stmt) => match stmt.step() { Some(ref stmt) => match stmt.step() {
@ -231,6 +225,7 @@ impl<'stmt> FallibleStreamingIterator for Rows<'stmt> {
} }
} }
#[inline]
fn get(&self) -> Option<&Row<'stmt>> { fn get(&self) -> Option<&Row<'stmt>> {
self.row.as_ref() self.row.as_ref()
} }

View File

@ -29,11 +29,13 @@ pub struct Session<'conn> {
impl Session<'_> { impl Session<'_> {
/// Create a new session object /// Create a new session object
#[inline]
pub fn new(db: &Connection) -> Result<Session<'_>> { pub fn new(db: &Connection) -> Result<Session<'_>> {
Session::new_with_name(db, DatabaseName::Main) Session::new_with_name(db, DatabaseName::Main)
} }
/// Create a new session object /// Create a new session object
#[inline]
pub fn new_with_name<'conn>( pub fn new_with_name<'conn>(
db: &'conn Connection, db: &'conn Connection,
name: DatabaseName<'_>, name: DatabaseName<'_>,
@ -120,6 +122,7 @@ impl Session<'_> {
} }
/// Write the set of changes represented by this session to `output`. /// Write the set of changes represented by this session to `output`.
#[inline]
pub fn changeset_strm(&mut self, output: &mut dyn Write) -> Result<()> { pub fn changeset_strm(&mut self, output: &mut dyn Write) -> Result<()> {
let output_ref = &output; let output_ref = &output;
check!(unsafe { check!(unsafe {
@ -133,6 +136,7 @@ impl Session<'_> {
} }
/// Generate a Patchset /// Generate a Patchset
#[inline]
pub fn patchset(&mut self) -> Result<Changeset> { pub fn patchset(&mut self) -> Result<Changeset> {
let mut n = 0; let mut n = 0;
let mut ps: *mut c_void = ptr::null_mut(); let mut ps: *mut c_void = ptr::null_mut();
@ -142,6 +146,7 @@ impl Session<'_> {
} }
/// Write the set of patches represented by this session to `output`. /// Write the set of patches represented by this session to `output`.
#[inline]
pub fn patchset_strm(&mut self, output: &mut dyn Write) -> Result<()> { pub fn patchset_strm(&mut self, output: &mut dyn Write) -> Result<()> {
let output_ref = &output; let output_ref = &output;
check!(unsafe { check!(unsafe {
@ -174,16 +179,19 @@ impl Session<'_> {
} }
/// Test if a changeset has recorded any changes /// Test if a changeset has recorded any changes
#[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
unsafe { ffi::sqlite3session_isempty(self.s) != 0 } unsafe { ffi::sqlite3session_isempty(self.s) != 0 }
} }
/// Query the current state of the session /// Query the current state of the session
#[inline]
pub fn is_enabled(&self) -> bool { pub fn is_enabled(&self) -> bool {
unsafe { ffi::sqlite3session_enable(self.s, -1) != 0 } unsafe { ffi::sqlite3session_enable(self.s, -1) != 0 }
} }
/// Enable or disable the recording of changes /// Enable or disable the recording of changes
#[inline]
pub fn set_enabled(&mut self, enabled: bool) { pub fn set_enabled(&mut self, enabled: bool) {
unsafe { unsafe {
ffi::sqlite3session_enable(self.s, if enabled { 1 } else { 0 }); ffi::sqlite3session_enable(self.s, if enabled { 1 } else { 0 });
@ -191,11 +199,13 @@ impl Session<'_> {
} }
/// Query the current state of the indirect flag /// Query the current state of the indirect flag
#[inline]
pub fn is_indirect(&self) -> bool { pub fn is_indirect(&self) -> bool {
unsafe { ffi::sqlite3session_indirect(self.s, -1) != 0 } unsafe { ffi::sqlite3session_indirect(self.s, -1) != 0 }
} }
/// Set or clear the indirect change flag /// Set or clear the indirect change flag
#[inline]
pub fn set_indirect(&mut self, indirect: bool) { pub fn set_indirect(&mut self, indirect: bool) {
unsafe { unsafe {
ffi::sqlite3session_indirect(self.s, if indirect { 1 } else { 0 }); ffi::sqlite3session_indirect(self.s, if indirect { 1 } else { 0 });
@ -204,6 +214,7 @@ impl Session<'_> {
} }
impl Drop for Session<'_> { impl Drop for Session<'_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
if self.filter.is_some() { if self.filter.is_some() {
self.table_filter(None::<fn(&str) -> bool>); self.table_filter(None::<fn(&str) -> bool>);
@ -213,6 +224,7 @@ impl Drop for Session<'_> {
} }
/// `feature = "session"` Invert a changeset /// `feature = "session"` Invert a changeset
#[inline]
pub fn invert_strm(input: &mut dyn Read, output: &mut dyn Write) -> Result<()> { pub fn invert_strm(input: &mut dyn Read, output: &mut dyn Write) -> Result<()> {
let input_ref = &input; let input_ref = &input;
let output_ref = &output; let output_ref = &output;
@ -228,6 +240,7 @@ pub fn invert_strm(input: &mut dyn Read, output: &mut dyn Write) -> Result<()> {
} }
/// `feature = "session"` Combine two changesets /// `feature = "session"` Combine two changesets
#[inline]
pub fn concat_strm( pub fn concat_strm(
input_a: &mut dyn Read, input_a: &mut dyn Read,
input_b: &mut dyn Read, input_b: &mut dyn Read,
@ -257,6 +270,7 @@ pub struct Changeset {
impl Changeset { impl Changeset {
/// Invert a changeset /// Invert a changeset
#[inline]
pub fn invert(&self) -> Result<Changeset> { pub fn invert(&self) -> Result<Changeset> {
let mut n = 0; let mut n = 0;
let mut cs = ptr::null_mut(); let mut cs = ptr::null_mut();
@ -267,6 +281,7 @@ impl Changeset {
} }
/// Create an iterator to traverse a changeset /// Create an iterator to traverse a changeset
#[inline]
pub fn iter(&self) -> Result<ChangesetIter<'_>> { pub fn iter(&self) -> Result<ChangesetIter<'_>> {
let mut it = ptr::null_mut(); let mut it = ptr::null_mut();
check!(unsafe { ffi::sqlite3changeset_start(&mut it as *mut *mut _, self.n, self.cs) }); check!(unsafe { ffi::sqlite3changeset_start(&mut it as *mut *mut _, self.n, self.cs) });
@ -278,6 +293,7 @@ impl Changeset {
} }
/// Concatenate two changeset objects /// Concatenate two changeset objects
#[inline]
pub fn concat(a: &Changeset, b: &Changeset) -> Result<Changeset> { pub fn concat(a: &Changeset, b: &Changeset) -> Result<Changeset> {
let mut n = 0; let mut n = 0;
let mut cs = ptr::null_mut(); let mut cs = ptr::null_mut();
@ -289,6 +305,7 @@ impl Changeset {
} }
impl Drop for Changeset { impl Drop for Changeset {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
ffi::sqlite3_free(self.cs); ffi::sqlite3_free(self.cs);
@ -306,6 +323,7 @@ pub struct ChangesetIter<'changeset> {
impl ChangesetIter<'_> { impl ChangesetIter<'_> {
/// Create an iterator on `input` /// Create an iterator on `input`
#[inline]
pub fn start_strm<'input>(input: &&'input mut dyn Read) -> Result<ChangesetIter<'input>> { pub fn start_strm<'input>(input: &&'input mut dyn Read) -> Result<ChangesetIter<'input>> {
let mut it = ptr::null_mut(); let mut it = ptr::null_mut();
check!(unsafe { check!(unsafe {
@ -327,6 +345,7 @@ impl FallibleStreamingIterator for ChangesetIter<'_> {
type Error = crate::error::Error; type Error = crate::error::Error;
type Item = ChangesetItem; type Item = ChangesetItem;
#[inline]
fn advance(&mut self) -> Result<()> { fn advance(&mut self) -> Result<()> {
let rc = unsafe { ffi::sqlite3changeset_next(self.it) }; let rc = unsafe { ffi::sqlite3changeset_next(self.it) };
match rc { match rc {
@ -342,6 +361,7 @@ impl FallibleStreamingIterator for ChangesetIter<'_> {
} }
} }
#[inline]
fn get(&self) -> Option<&ChangesetItem> { fn get(&self) -> Option<&ChangesetItem> {
self.item.as_ref() self.item.as_ref()
} }
@ -357,27 +377,32 @@ pub struct Operation<'item> {
impl Operation<'_> { impl Operation<'_> {
/// Returns the table name. /// Returns the table name.
#[inline]
pub fn table_name(&self) -> &str { pub fn table_name(&self) -> &str {
self.table_name self.table_name
} }
/// Returns the number of columns in table /// Returns the number of columns in table
#[inline]
pub fn number_of_columns(&self) -> i32 { pub fn number_of_columns(&self) -> i32 {
self.number_of_columns self.number_of_columns
} }
/// Returns the action code. /// Returns the action code.
#[inline]
pub fn code(&self) -> Action { pub fn code(&self) -> Action {
self.code self.code
} }
/// Returns `true` for an 'indirect' change. /// Returns `true` for an 'indirect' change.
#[inline]
pub fn indirect(&self) -> bool { pub fn indirect(&self) -> bool {
self.indirect self.indirect
} }
} }
impl Drop for ChangesetIter<'_> { impl Drop for ChangesetIter<'_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
ffi::sqlite3changeset_finalize(self.it); ffi::sqlite3changeset_finalize(self.it);
@ -397,6 +422,7 @@ impl ChangesetItem {
/// ///
/// May only be called with an `SQLITE_CHANGESET_DATA` or /// May only be called with an `SQLITE_CHANGESET_DATA` or
/// `SQLITE_CHANGESET_CONFLICT` conflict handler callback. /// `SQLITE_CHANGESET_CONFLICT` conflict handler callback.
#[inline]
pub fn conflict(&self, col: usize) -> Result<ValueRef<'_>> { pub fn conflict(&self, col: usize) -> Result<ValueRef<'_>> {
unsafe { unsafe {
let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut();
@ -413,6 +439,7 @@ impl ChangesetItem {
/// ///
/// May only be called with an `SQLITE_CHANGESET_FOREIGN_KEY` conflict /// May only be called with an `SQLITE_CHANGESET_FOREIGN_KEY` conflict
/// handler callback. /// handler callback.
#[inline]
pub fn fk_conflicts(&self) -> Result<i32> { pub fn fk_conflicts(&self) -> Result<i32> {
unsafe { unsafe {
let mut p_out = 0; let mut p_out = 0;
@ -425,6 +452,7 @@ impl ChangesetItem {
/// ///
/// May only be called if the type of change is either `SQLITE_UPDATE` or /// May only be called if the type of change is either `SQLITE_UPDATE` or
/// `SQLITE_INSERT`. /// `SQLITE_INSERT`.
#[inline]
pub fn new_value(&self, col: usize) -> Result<ValueRef<'_>> { pub fn new_value(&self, col: usize) -> Result<ValueRef<'_>> {
unsafe { unsafe {
let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut();
@ -437,6 +465,7 @@ impl ChangesetItem {
/// ///
/// May only be called if the type of change is either `SQLITE_DELETE` or /// May only be called if the type of change is either `SQLITE_DELETE` or
/// `SQLITE_UPDATE`. /// `SQLITE_UPDATE`.
#[inline]
pub fn old_value(&self, col: usize) -> Result<ValueRef<'_>> { pub fn old_value(&self, col: usize) -> Result<ValueRef<'_>> {
unsafe { unsafe {
let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut();
@ -446,6 +475,7 @@ impl ChangesetItem {
} }
/// Obtain the current operation /// Obtain the current operation
#[inline]
pub fn op(&self) -> Result<Operation<'_>> { pub fn op(&self) -> Result<Operation<'_>> {
let mut number_of_columns = 0; let mut number_of_columns = 0;
let mut code = 0; let mut code = 0;
@ -471,6 +501,7 @@ impl ChangesetItem {
} }
/// Obtain the primary key definition of a table /// Obtain the primary key definition of a table
#[inline]
pub fn pk(&self) -> Result<&[u8]> { pub fn pk(&self) -> Result<&[u8]> {
let mut number_of_columns = 0; let mut number_of_columns = 0;
unsafe { unsafe {
@ -493,6 +524,7 @@ pub struct Changegroup {
impl Changegroup { impl Changegroup {
/// Create a new change group. /// Create a new change group.
#[inline]
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {
let mut cg = ptr::null_mut(); let mut cg = ptr::null_mut();
check!(unsafe { ffi::sqlite3changegroup_new(&mut cg) }); check!(unsafe { ffi::sqlite3changegroup_new(&mut cg) });
@ -500,12 +532,14 @@ impl Changegroup {
} }
/// Add a changeset /// Add a changeset
#[inline]
pub fn add(&mut self, cs: &Changeset) -> Result<()> { pub fn add(&mut self, cs: &Changeset) -> Result<()> {
check!(unsafe { ffi::sqlite3changegroup_add(self.cg, cs.n, cs.cs) }); check!(unsafe { ffi::sqlite3changegroup_add(self.cg, cs.n, cs.cs) });
Ok(()) Ok(())
} }
/// Add a changeset read from `input` to this change group. /// Add a changeset read from `input` to this change group.
#[inline]
pub fn add_stream(&mut self, input: &mut dyn Read) -> Result<()> { pub fn add_stream(&mut self, input: &mut dyn Read) -> Result<()> {
let input_ref = &input; let input_ref = &input;
check!(unsafe { check!(unsafe {
@ -519,6 +553,7 @@ impl Changegroup {
} }
/// Obtain a composite Changeset /// Obtain a composite Changeset
#[inline]
pub fn output(&mut self) -> Result<Changeset> { pub fn output(&mut self) -> Result<Changeset> {
let mut n = 0; let mut n = 0;
let mut output: *mut c_void = ptr::null_mut(); let mut output: *mut c_void = ptr::null_mut();
@ -527,6 +562,7 @@ impl Changegroup {
} }
/// Write the combined set of changes to `output`. /// Write the combined set of changes to `output`.
#[inline]
pub fn output_strm(&mut self, output: &mut dyn Write) -> Result<()> { pub fn output_strm(&mut self, output: &mut dyn Write) -> Result<()> {
let output_ref = &output; let output_ref = &output;
check!(unsafe { check!(unsafe {
@ -541,6 +577,7 @@ impl Changegroup {
} }
impl Drop for Changegroup { impl Drop for Changegroup {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
ffi::sqlite3changegroup_delete(self.cg); ffi::sqlite3changegroup_delete(self.cg);

View File

@ -80,6 +80,7 @@ impl Statement<'_> {
/// 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
/// underlying SQLite call fails. /// underlying SQLite call fails.
#[inline]
pub fn execute<P: Params>(&mut self, params: P) -> Result<usize> { pub fn execute<P: Params>(&mut self, params: P) -> Result<usize> {
params.bind_in(self)?; params.bind_in(self)?;
self.execute_with_bound_parameters() self.execute_with_bound_parameters()
@ -104,6 +105,7 @@ impl 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
/// underlying SQLite call fails. /// underlying SQLite call fails.
#[deprecated = "You can use `execute` with named params now."] #[deprecated = "You can use `execute` with named params now."]
#[inline]
pub fn execute_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<usize> { pub fn execute_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<usize> {
self.execute(params) self.execute(params)
} }
@ -121,6 +123,7 @@ impl Statement<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if no row is inserted or many rows are inserted. /// Will return `Err` if no row is inserted or many rows are inserted.
#[inline]
pub fn insert<P: Params>(&mut self, params: P) -> Result<i64> { pub fn insert<P: Params>(&mut self, params: P) -> Result<i64> {
let changes = self.execute(params)?; let changes = self.execute(params)?;
match changes { match changes {
@ -215,6 +218,7 @@ impl Statement<'_> {
/// ## Failure /// ## Failure
/// ///
/// Will return `Err` if binding parameters fails. /// Will return `Err` if binding parameters fails.
#[inline]
pub fn query<P: Params>(&mut self, params: P) -> Result<Rows<'_>> { pub fn query<P: Params>(&mut self, params: P) -> Result<Rows<'_>> {
self.check_readonly()?; self.check_readonly()?;
params.bind_in(self)?; params.bind_in(self)?;
@ -246,6 +250,8 @@ impl Statement<'_> {
/// `f` is used to tranform the _streaming_ iterator into a _standard_ /// `f` is used to tranform the _streaming_ iterator into a _standard_
/// iterator. /// iterator.
/// ///
/// This is equivalent to `stmt.query(params)?.mapped(f)`.
///
/// ## Example /// ## Example
/// ///
/// ### Use with positional params /// ### Use with positional params
@ -289,8 +295,7 @@ impl Statement<'_> {
P: Params, P: Params,
F: FnMut(&Row<'_>) -> Result<T>, F: FnMut(&Row<'_>) -> Result<T>,
{ {
let rows = self.query(params)?; self.query(params).map(|rows| rows.mapped(f))
Ok(MappedRows::new(rows, f))
} }
/// Execute the prepared statement with named parameter(s), returning an /// Execute the prepared statement with named parameter(s), returning an
@ -327,6 +332,8 @@ impl Statement<'_> {
/// rows, where the function returns a `Result` with `Error` type /// rows, where the function returns a `Result` with `Error` type
/// implementing `std::convert::From<Error>` (so errors can be unified). /// implementing `std::convert::From<Error>` (so errors can be unified).
/// ///
/// This is equivalent to `stmt.query(params)?.and_then(f)`.
///
/// ## Example /// ## Example
/// ///
/// ### Use with named params /// ### Use with named params
@ -376,14 +383,14 @@ impl Statement<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if binding parameters fails. /// Will return `Err` if binding parameters fails.
#[inline]
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: convert::From<Error>,
F: FnMut(&Row<'_>) -> Result<T, E>, F: FnMut(&Row<'_>) -> Result<T, E>,
{ {
let rows = self.query(params)?; self.query(params).map(|rows| rows.and_then(f))
Ok(AndThenRows::new(rows, f))
} }
/// Execute the prepared statement with named parameter(s), returning an /// Execute the prepared statement with named parameter(s), returning an
@ -416,6 +423,7 @@ impl Statement<'_> {
/// Return `true` if a query in the SQL statement it executes returns one /// Return `true` if a query in the SQL statement it executes returns one
/// or more rows and `false` if the SQL returns an empty set. /// or more rows and `false` if the SQL returns an empty set.
#[inline]
pub fn exists<P: Params>(&mut self, params: P) -> Result<bool> { pub fn exists<P: Params>(&mut self, params: P) -> Result<bool> {
let mut rows = self.query(params)?; let mut rows = self.query(params)?;
let exists = rows.next()?.is_some(); let exists = rows.next()?.is_some();
@ -478,6 +486,7 @@ impl Statement<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[inline]
pub fn finalize(mut self) -> Result<()> { pub fn finalize(mut self) -> Result<()> {
self.finalize_() self.finalize_()
} }
@ -501,10 +510,12 @@ impl Statement<'_> {
/// ///
/// Will return Err if `name` is invalid. Will return Ok(None) if the name /// Will return Err if `name` is invalid. Will return Ok(None) if the name
/// is valid but not a bound parameter of this statement. /// is valid but not a bound parameter of this statement.
#[inline]
pub fn parameter_index(&self, name: &str) -> Result<Option<usize>> { pub fn parameter_index(&self, name: &str) -> Result<Option<usize>> {
Ok(self.stmt.bind_parameter_index(name)) Ok(self.stmt.bind_parameter_index(name))
} }
#[inline]
pub(crate) fn bind_parameters<P>(&mut self, params: P) -> Result<()> pub(crate) fn bind_parameters<P>(&mut self, params: P) -> Result<()>
where where
P: IntoIterator, P: IntoIterator,
@ -526,6 +537,7 @@ impl Statement<'_> {
} }
} }
#[inline]
pub(crate) fn bind_parameters_named<T: ?Sized + ToSql>( pub(crate) fn bind_parameters_named<T: ?Sized + ToSql>(
&mut self, &mut self,
params: &[(&str, &T)], params: &[(&str, &T)],
@ -542,6 +554,7 @@ impl Statement<'_> {
} }
/// Return the number of parameters that can be bound to this statement. /// Return the number of parameters that can be bound to this statement.
#[inline]
pub fn parameter_count(&self) -> usize { pub fn parameter_count(&self) -> usize {
self.stmt.bind_parameter_count() self.stmt.bind_parameter_count()
} }
@ -584,6 +597,7 @@ impl Statement<'_> {
/// Ok(()) /// Ok(())
/// } /// }
/// ``` /// ```
#[inline]
pub fn raw_bind_parameter<T: ToSql>( pub fn raw_bind_parameter<T: ToSql>(
&mut self, &mut self,
one_based_col_index: usize, one_based_col_index: usize,
@ -608,6 +622,7 @@ impl Statement<'_> {
/// ///
/// Will return `Err` if the executed statement returns rows (in which case /// Will return `Err` if the executed statement returns rows (in which case
/// `query` should be used instead), or the underlying SQLite call fails. /// `query` should be used instead), or the underlying SQLite call fails.
#[inline]
pub fn raw_execute(&mut self) -> Result<usize> { pub fn raw_execute(&mut self) -> Result<usize> {
self.execute_with_bound_parameters() self.execute_with_bound_parameters()
} }
@ -624,11 +639,13 @@ impl Statement<'_> {
/// ///
/// Note that if the SQL does not return results, [`Statement::raw_execute`] /// Note that if the SQL does not return results, [`Statement::raw_execute`]
/// should be used instead. /// should be used instead.
#[inline]
pub fn raw_query(&mut self) -> Rows<'_> { pub fn raw_query(&mut self) -> Rows<'_> {
Rows::new(self) Rows::new(self)
} }
fn bind_parameter(&self, param: &dyn ToSql, col: usize) -> Result<()> { // generic because many of these branches can constant fold away.
fn bind_parameter<P: ?Sized + ToSql>(&self, param: &P, 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() };
@ -680,6 +697,7 @@ impl Statement<'_> {
}) })
} }
#[inline]
fn execute_with_bound_parameters(&mut self) -> Result<usize> { fn execute_with_bound_parameters(&mut self) -> Result<usize> {
self.check_update()?; self.check_update()?;
let r = self.stmt.step(); let r = self.stmt.step();
@ -691,6 +709,7 @@ impl Statement<'_> {
} }
} }
#[inline]
fn finalize_(&mut self) -> Result<()> { fn finalize_(&mut self) -> Result<()> {
let mut stmt = unsafe { RawStatement::new(ptr::null_mut(), 0) }; let mut stmt = unsafe { RawStatement::new(ptr::null_mut(), 0) };
mem::swap(&mut stmt, &mut self.stmt); mem::swap(&mut stmt, &mut self.stmt);
@ -748,17 +767,20 @@ impl Statement<'_> {
} }
/// Get the value for one of the status counters for this statement. /// Get the value for one of the status counters for this statement.
#[inline]
pub fn get_status(&self, status: StatementStatus) -> i32 { pub fn get_status(&self, status: StatementStatus) -> i32 {
self.stmt.get_status(status, false) self.stmt.get_status(status, false)
} }
/// Reset the value of one of the status counters for this statement, /// Reset the value of one of the status counters for this statement,
#[inline]
/// returning the value it had before resetting. /// returning the value it had before resetting.
pub fn reset_status(&self, status: StatementStatus) -> i32 { pub fn reset_status(&self, status: StatementStatus) -> i32 {
self.stmt.get_status(status, true) self.stmt.get_status(status, true)
} }
#[cfg(feature = "extra_check")] #[cfg(feature = "extra_check")]
#[inline]
pub(crate) fn check_no_tail(&self) -> Result<()> { pub(crate) fn check_no_tail(&self) -> Result<()> {
if self.stmt.has_tail() { if self.stmt.has_tail() {
Err(Error::MultipleStatement) Err(Error::MultipleStatement)
@ -776,6 +798,7 @@ impl Statement<'_> {
/// Safety: This is unsafe, because using `sqlite3_stmt` after the /// Safety: This is unsafe, because using `sqlite3_stmt` after the
/// connection has closed is illegal, but `RawStatement` does not enforce /// connection has closed is illegal, but `RawStatement` does not enforce
/// this, as it loses our protective `'conn` lifetime bound. /// this, as it loses our protective `'conn` lifetime bound.
#[inline]
pub(crate) unsafe fn into_raw(mut self) -> RawStatement { pub(crate) unsafe fn into_raw(mut self) -> RawStatement {
let mut stmt = RawStatement::new(ptr::null_mut(), 0); let mut stmt = RawStatement::new(ptr::null_mut(), 0);
mem::swap(&mut stmt, &mut self.stmt); mem::swap(&mut stmt, &mut self.stmt);
@ -800,12 +823,14 @@ impl fmt::Debug for Statement<'_> {
impl Drop for Statement<'_> { impl Drop for Statement<'_> {
#[allow(unused_must_use)] #[allow(unused_must_use)]
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.finalize_(); self.finalize_();
} }
} }
impl Statement<'_> { impl Statement<'_> {
#[inline]
pub(super) fn new(conn: &Connection, stmt: RawStatement) -> Statement<'_> { pub(super) fn new(conn: &Connection, stmt: RawStatement) -> Statement<'_> {
Statement { conn, stmt } Statement { conn, stmt }
} }
@ -866,6 +891,7 @@ impl Statement<'_> {
} }
} }
#[inline]
pub(super) fn step(&self) -> Result<bool> { pub(super) fn step(&self) -> Result<bool> {
match self.stmt.step() { match self.stmt.step() {
ffi::SQLITE_ROW => Ok(true), ffi::SQLITE_ROW => Ok(true),
@ -874,6 +900,7 @@ impl Statement<'_> {
} }
} }
#[inline]
pub(super) fn reset(&self) -> c_int { pub(super) fn reset(&self) -> c_int {
self.stmt.reset() self.stmt.reset()
} }

View File

@ -55,6 +55,7 @@ pub unsafe fn config_log(callback: Option<fn(c_int, &str)>) -> Result<()> {
/// `feature = "trace"` Write a message into the error log established by /// `feature = "trace"` Write a message into the error log established by
/// `config_log`. /// `config_log`.
#[inline]
pub fn log(err_code: c_int, msg: &str) { pub fn log(err_code: c_int, msg: &str) {
let msg = CString::new(msg).expect("SQLite log messages cannot contain embedded zeroes"); let msg = CString::new(msg).expect("SQLite log messages cannot contain embedded zeroes");
unsafe { unsafe {

View File

@ -102,6 +102,7 @@ impl Transaction<'_> {
/// 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 transactions on the same connection. For cases /// so as to prevent nested transactions on the same connection. For cases
/// where this is unacceptable, [`Transaction::new_unchecked`] is available. /// where this is unacceptable, [`Transaction::new_unchecked`] is available.
#[inline]
pub fn new(conn: &mut Connection, behavior: TransactionBehavior) -> Result<Transaction<'_>> { pub fn new(conn: &mut Connection, behavior: TransactionBehavior) -> Result<Transaction<'_>> {
Self::new_unchecked(conn, behavior) Self::new_unchecked(conn, behavior)
} }
@ -111,6 +112,7 @@ impl Transaction<'_> {
/// If a transaction is already open, this will return an error. Where /// If a transaction is already open, this will return an error. Where
/// possible, [`Transaction::new`] should be preferred, as it provides a /// possible, [`Transaction::new`] should be preferred, as it provides a
/// compile-time guarantee that transactions are not nested. /// compile-time guarantee that transactions are not nested.
#[inline]
pub fn new_unchecked( pub fn new_unchecked(
conn: &Connection, conn: &Connection,
behavior: TransactionBehavior, behavior: TransactionBehavior,
@ -153,42 +155,50 @@ impl Transaction<'_> {
/// tx.commit() /// tx.commit()
/// } /// }
/// ``` /// ```
#[inline]
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()`.
#[inline]
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)
} }
/// Get the current setting for what happens to the transaction when it is /// Get the current setting for what happens to the transaction when it is
/// dropped. /// dropped.
#[inline]
pub fn drop_behavior(&self) -> DropBehavior { pub fn drop_behavior(&self) -> DropBehavior {
self.drop_behavior self.drop_behavior
} }
/// Configure the transaction to perform the specified action when it is /// Configure the transaction to perform the specified action when it is
/// dropped. /// dropped.
#[inline]
pub fn set_drop_behavior(&mut self, drop_behavior: DropBehavior) { pub fn set_drop_behavior(&mut self, drop_behavior: DropBehavior) {
self.drop_behavior = drop_behavior self.drop_behavior = drop_behavior
} }
/// A convenience method which consumes and commits a transaction. /// A convenience method which consumes and commits a transaction.
#[inline]
pub fn commit(mut self) -> Result<()> { pub fn commit(mut self) -> Result<()> {
self.commit_() self.commit_()
} }
#[inline]
fn commit_(&mut self) -> Result<()> { fn commit_(&mut self) -> Result<()> {
self.conn.execute_batch("COMMIT")?; self.conn.execute_batch("COMMIT")?;
Ok(()) Ok(())
} }
/// A convenience method which consumes and rolls back a transaction. /// A convenience method which consumes and rolls back a transaction.
#[inline]
pub fn rollback(mut self) -> Result<()> { pub fn rollback(mut self) -> Result<()> {
self.rollback_() self.rollback_()
} }
#[inline]
fn rollback_(&mut self) -> Result<()> { fn rollback_(&mut self) -> Result<()> {
self.conn.execute_batch("ROLLBACK")?; self.conn.execute_batch("ROLLBACK")?;
Ok(()) Ok(())
@ -199,10 +209,12 @@ impl Transaction<'_> {
/// ///
/// Functionally equivalent to the `Drop` implementation, but allows /// Functionally equivalent to the `Drop` implementation, but allows
/// callers to see any errors that occur. /// callers to see any errors that occur.
#[inline]
pub fn finish(mut self) -> Result<()> { pub fn finish(mut self) -> Result<()> {
self.finish_() self.finish_()
} }
#[inline]
fn finish_(&mut self) -> Result<()> { fn finish_(&mut self) -> Result<()> {
if self.conn.is_autocommit() { if self.conn.is_autocommit() {
return Ok(()); return Ok(());
@ -219,6 +231,7 @@ impl Transaction<'_> {
impl Deref for Transaction<'_> { impl Deref for Transaction<'_> {
type Target = Connection; type Target = Connection;
#[inline]
fn deref(&self) -> &Connection { fn deref(&self) -> &Connection {
self.conn self.conn
} }
@ -226,12 +239,14 @@ impl Deref for Transaction<'_> {
#[allow(unused_must_use)] #[allow(unused_must_use)]
impl Drop for Transaction<'_> { impl Drop for Transaction<'_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.finish_(); self.finish_();
} }
} }
impl Savepoint<'_> { impl Savepoint<'_> {
#[inline]
fn with_depth_and_name<T: Into<String>>( fn with_depth_and_name<T: Into<String>>(
conn: &Connection, conn: &Connection,
depth: u32, depth: u32,
@ -248,48 +263,57 @@ impl Savepoint<'_> {
}) })
} }
#[inline]
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.
#[inline]
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.
#[inline]
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.
#[inline]
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.
#[inline]
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)
} }
/// Get the current setting for what happens to the savepoint when it is /// Get the current setting for what happens to the savepoint when it is
/// dropped. /// dropped.
#[inline]
pub fn drop_behavior(&self) -> DropBehavior { pub fn drop_behavior(&self) -> DropBehavior {
self.drop_behavior self.drop_behavior
} }
/// Configure the savepoint to perform the specified action when it is /// Configure the savepoint to perform the specified action when it is
/// dropped. /// dropped.
#[inline]
pub fn set_drop_behavior(&mut self, drop_behavior: DropBehavior) { pub fn set_drop_behavior(&mut self, drop_behavior: DropBehavior) {
self.drop_behavior = drop_behavior self.drop_behavior = drop_behavior
} }
/// A convenience method which consumes and commits a savepoint. /// A convenience method which consumes and commits a savepoint.
#[inline]
pub fn commit(mut self) -> Result<()> { pub fn commit(mut self) -> Result<()> {
self.commit_() self.commit_()
} }
#[inline]
fn commit_(&mut self) -> Result<()> { fn commit_(&mut self) -> Result<()> {
self.conn.execute_batch(&format!("RELEASE {}", self.name))?; self.conn.execute_batch(&format!("RELEASE {}", self.name))?;
self.committed = true; self.committed = true;
@ -302,6 +326,7 @@ impl Savepoint<'_> {
/// ///
/// Unlike `Transaction`s, savepoints remain active after they have been /// Unlike `Transaction`s, savepoints remain active after they have been
/// rolled back, and can be rolled back again or committed. /// rolled back, and can be rolled back again or committed.
#[inline]
pub fn rollback(&mut self) -> Result<()> { pub fn rollback(&mut self) -> Result<()> {
self.conn self.conn
.execute_batch(&format!("ROLLBACK TO {}", self.name)) .execute_batch(&format!("ROLLBACK TO {}", self.name))
@ -312,10 +337,12 @@ impl Savepoint<'_> {
/// ///
/// Functionally equivalent to the `Drop` implementation, but allows /// Functionally equivalent to the `Drop` implementation, but allows
/// callers to see any errors that occur. /// callers to see any errors that occur.
#[inline]
pub fn finish(mut self) -> Result<()> { pub fn finish(mut self) -> Result<()> {
self.finish_() self.finish_()
} }
#[inline]
fn finish_(&mut self) -> Result<()> { fn finish_(&mut self) -> Result<()> {
if self.committed { if self.committed {
return Ok(()); return Ok(());
@ -332,6 +359,7 @@ impl Savepoint<'_> {
impl Deref for Savepoint<'_> { impl Deref for Savepoint<'_> {
type Target = Connection; type Target = Connection;
#[inline]
fn deref(&self) -> &Connection { fn deref(&self) -> &Connection {
self.conn self.conn
} }
@ -339,6 +367,7 @@ impl Deref for Savepoint<'_> {
#[allow(unused_must_use)] #[allow(unused_must_use)]
impl Drop for Savepoint<'_> { impl Drop for Savepoint<'_> {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
self.finish_(); self.finish_();
} }
@ -370,6 +399,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[inline]
pub fn transaction(&mut self) -> Result<Transaction<'_>> { pub fn transaction(&mut self) -> Result<Transaction<'_>> {
Transaction::new(self, TransactionBehavior::Deferred) Transaction::new(self, TransactionBehavior::Deferred)
} }
@ -381,6 +411,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[inline]
pub fn transaction_with_behavior( pub fn transaction_with_behavior(
&mut self, &mut self,
behavior: TransactionBehavior, behavior: TransactionBehavior,
@ -448,6 +479,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[inline]
pub fn savepoint(&mut self) -> Result<Savepoint<'_>> { pub fn savepoint(&mut self) -> Result<Savepoint<'_>> {
Savepoint::new(self) Savepoint::new(self)
} }
@ -459,6 +491,7 @@ impl Connection {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if the underlying SQLite call fails. /// Will return `Err` if the underlying SQLite call fails.
#[inline]
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)
} }

View File

@ -9,6 +9,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 {
#[inline]
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))
@ -17,6 +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 {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value value
.as_str() .as_str()
@ -29,6 +31,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 {
#[inline]
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))
@ -55,6 +58,7 @@ impl FromSql for NaiveTime {
/// ISO 8601 combined date and time without timezone => /// ISO 8601 combined date and time without timezone =>
/// "YYYY-MM-DDTHH:MM:SS.SSS" /// "YYYY-MM-DDTHH:MM:SS.SSS"
impl ToSql for NaiveDateTime { impl ToSql for NaiveDateTime {
#[inline]
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))
@ -84,6 +88,7 @@ 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> {
#[inline]
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()))
} }
@ -120,6 +125,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> {
#[inline]
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))

View File

@ -94,6 +94,7 @@ pub trait FromSql: Sized {
macro_rules! from_sql_integral( macro_rules! from_sql_integral(
($t:ident) => ( ($t:ident) => (
impl FromSql for $t { impl FromSql for $t {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
let i = i64::column_result(value)?; let i = i64::column_result(value)?;
i.try_into().map_err(|_| FromSqlError::OutOfRange(i)) i.try_into().map_err(|_| FromSqlError::OutOfRange(i))
@ -114,12 +115,14 @@ from_sql_integral!(u64);
from_sql_integral!(usize); from_sql_integral!(usize);
impl FromSql for i64 { impl FromSql for i64 {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value.as_i64() value.as_i64()
} }
} }
impl FromSql for f32 { impl FromSql for f32 {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
match value { match value {
ValueRef::Integer(i) => Ok(i as f32), ValueRef::Integer(i) => Ok(i as f32),
@ -130,6 +133,7 @@ impl FromSql for f32 {
} }
impl FromSql for f64 { impl FromSql for f64 {
#[inline]
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),
@ -140,36 +144,42 @@ impl FromSql for f64 {
} }
impl FromSql for bool { impl FromSql for bool {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
i64::column_result(value).map(|i| !matches!(i, 0)) i64::column_result(value).map(|i| !matches!(i, 0))
} }
} }
impl FromSql for String { impl FromSql for String {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value.as_str().map(ToString::to_string) value.as_str().map(ToString::to_string)
} }
} }
impl FromSql for Box<str> { impl FromSql for Box<str> {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value.as_str().map(Into::into) value.as_str().map(Into::into)
} }
} }
impl FromSql for std::rc::Rc<str> { impl FromSql for std::rc::Rc<str> {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value.as_str().map(Into::into) value.as_str().map(Into::into)
} }
} }
impl FromSql for std::sync::Arc<str> { impl FromSql for std::sync::Arc<str> {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value.as_str().map(Into::into) value.as_str().map(Into::into)
} }
} }
impl FromSql for Vec<u8> { impl FromSql for Vec<u8> {
#[inline]
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())
} }
@ -177,6 +187,7 @@ impl FromSql for Vec<u8> {
#[cfg(feature = "i128_blob")] #[cfg(feature = "i128_blob")]
impl FromSql for i128 { impl FromSql for i128 {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
@ -192,6 +203,7 @@ impl FromSql for i128 {
#[cfg(feature = "uuid")] #[cfg(feature = "uuid")]
impl FromSql for uuid::Uuid { impl FromSql for uuid::Uuid {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value value
.as_blob() .as_blob()
@ -204,6 +216,7 @@ impl FromSql for uuid::Uuid {
} }
impl<T: FromSql> FromSql for Option<T> { impl<T: FromSql> FromSql for Option<T> {
#[inline]
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),
@ -213,6 +226,7 @@ impl<T: FromSql> FromSql for Option<T> {
} }
impl FromSql for Value { impl FromSql for Value {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
Ok(value.into()) Ok(value.into())
} }

View File

@ -119,11 +119,11 @@ 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 => f.pad("Null"),
Type::Integer => write!(f, "Integer"), Type::Integer => f.pad("Integer"),
Type::Real => write!(f, "Real"), Type::Real => f.pad("Real"),
Type::Text => write!(f, "Text"), Type::Text => f.pad("Text"),
Type::Blob => write!(f, "Blob"), Type::Blob => f.pad("Blob"),
} }
} }
} }
@ -260,9 +260,9 @@ mod test {
assert_eq!("text", row.get::<_, String>(1).unwrap()); assert_eq!("text", row.get::<_, String>(1).unwrap());
assert_eq!(1, row.get::<_, c_int>(2).unwrap()); assert_eq!(1, row.get::<_, c_int>(2).unwrap());
assert!((1.5 - row.get::<_, c_double>(3).unwrap()).abs() < EPSILON); assert!((1.5 - row.get::<_, c_double>(3).unwrap()).abs() < EPSILON);
assert!(row.get::<_, Option<c_int>>(4).unwrap().is_none()); assert_eq!(row.get::<_, Option<c_int>>(4).unwrap(), None);
assert!(row.get::<_, Option<c_double>>(4).unwrap().is_none()); assert_eq!(row.get::<_, Option<c_double>>(4).unwrap(), None);
assert!(row.get::<_, Option<String>>(4).unwrap().is_none()); assert_eq!(row.get::<_, Option<String>>(4).unwrap(), None);
// check some invalid types // check some invalid types

View File

@ -7,6 +7,7 @@ use crate::Result;
/// Serialize JSON `Value` to text. /// Serialize JSON `Value` to text.
impl ToSql for Value { impl ToSql for Value {
#[inline]
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()))
} }
@ -14,6 +15,7 @@ impl ToSql for Value {
/// Deserialize text/blob to JSON `Value`. /// Deserialize text/blob to JSON `Value`.
impl FromSql for Value { impl FromSql for Value {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
match value { match value {
ValueRef::Text(s) => serde_json::from_slice(s), ValueRef::Text(s) => serde_json::from_slice(s),

View File

@ -8,6 +8,7 @@ const SQLITE_DATETIME_FMT: &str = "%Y-%m-%dT%H:%M:%S.%NZ";
const SQLITE_DATETIME_FMT_LEGACY: &str = "%Y-%m-%d %H:%M:%S:%N %z"; const SQLITE_DATETIME_FMT_LEGACY: &str = "%Y-%m-%d %H:%M:%S:%N %z";
impl ToSql for OffsetDateTime { impl ToSql for OffsetDateTime {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
let time_string = self.to_offset(UtcOffset::UTC).format(SQLITE_DATETIME_FMT); let time_string = self.to_offset(UtcOffset::UTC).format(SQLITE_DATETIME_FMT);
Ok(ToSqlOutput::from(time_string)) Ok(ToSqlOutput::from(time_string))

View File

@ -32,6 +32,7 @@ impl<'a, T: ?Sized> From<&'a T> for ToSqlOutput<'a>
where where
&'a T: Into<ValueRef<'a>>, &'a T: Into<ValueRef<'a>>,
{ {
#[inline]
fn from(t: &'a T) -> Self { fn from(t: &'a T) -> Self {
ToSqlOutput::Borrowed(t.into()) ToSqlOutput::Borrowed(t.into())
} }
@ -45,6 +46,7 @@ where
macro_rules! from_value( macro_rules! from_value(
($t:ty) => ( ($t:ty) => (
impl From<$t> for ToSqlOutput<'_> { impl From<$t> for ToSqlOutput<'_> {
#[inline]
fn from(t: $t) -> Self { ToSqlOutput::Owned(t.into())} fn from(t: $t) -> Self { ToSqlOutput::Owned(t.into())}
} }
) )
@ -74,6 +76,7 @@ from_value!(i128);
from_value!(uuid::Uuid); from_value!(uuid::Uuid);
impl ToSql for ToSqlOutput<'_> { impl ToSql for ToSqlOutput<'_> {
#[inline]
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),
@ -95,24 +98,28 @@ pub trait ToSql {
} }
impl<T: ToSql + ToOwned + ?Sized> ToSql for Cow<'_, T> { impl<T: ToSql + ToOwned + ?Sized> ToSql for Cow<'_, T> {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
self.as_ref().to_sql() self.as_ref().to_sql()
} }
} }
impl<T: ToSql + ?Sized> ToSql for Box<T> { impl<T: ToSql + ?Sized> ToSql for Box<T> {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
self.as_ref().to_sql() self.as_ref().to_sql()
} }
} }
impl<T: ToSql + ?Sized> ToSql for std::rc::Rc<T> { impl<T: ToSql + ?Sized> ToSql for std::rc::Rc<T> {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
self.as_ref().to_sql() self.as_ref().to_sql()
} }
} }
impl<T: ToSql + ?Sized> ToSql for std::sync::Arc<T> { impl<T: ToSql + ?Sized> ToSql for std::sync::Arc<T> {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
self.as_ref().to_sql() self.as_ref().to_sql()
} }
@ -133,6 +140,7 @@ impl<T: ToSql + ?Sized> ToSql for std::sync::Arc<T> {
macro_rules! to_sql_self( macro_rules! to_sql_self(
($t:ty) => ( ($t:ty) => (
impl ToSql for $t { impl ToSql for $t {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::from(*self)) Ok(ToSqlOutput::from(*self))
} }
@ -162,6 +170,7 @@ to_sql_self!(uuid::Uuid);
macro_rules! to_sql_self_fallible( macro_rules! to_sql_self_fallible(
($t:ty) => ( ($t:ty) => (
impl ToSql for $t { impl ToSql for $t {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::Owned(Value::Integer( Ok(ToSqlOutput::Owned(Value::Integer(
i64::try_from(*self).map_err( i64::try_from(*self).map_err(
@ -182,42 +191,49 @@ impl<T: ?Sized> ToSql for &'_ T
where where
T: ToSql, T: ToSql,
{ {
#[inline]
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 {
#[inline]
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 {
#[inline]
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> {
#[inline]
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] {
#[inline]
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 {
#[inline]
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> {
#[inline]
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)),

View File

@ -5,6 +5,7 @@ use url::Url;
/// Serialize `Url` to text. /// Serialize `Url` to text.
impl ToSql for Url { impl ToSql for Url {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::from(self.as_str())) Ok(ToSqlOutput::from(self.as_str()))
} }
@ -12,6 +13,7 @@ impl ToSql for Url {
/// Deserialize text to `Url`. /// Deserialize text to `Url`.
impl FromSql for Url { impl FromSql for Url {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
match value { match value {
ValueRef::Text(s) => { ValueRef::Text(s) => {

View File

@ -19,18 +19,21 @@ pub enum Value {
} }
impl From<Null> for Value { impl From<Null> for Value {
#[inline]
fn from(_: Null) -> Value { fn from(_: Null) -> Value {
Value::Null Value::Null
} }
} }
impl From<bool> for Value { impl From<bool> for Value {
#[inline]
fn from(i: bool) -> Value { fn from(i: bool) -> Value {
Value::Integer(i as i64) Value::Integer(i as i64)
} }
} }
impl From<isize> for Value { impl From<isize> for Value {
#[inline]
fn from(i: isize) -> Value { fn from(i: isize) -> Value {
Value::Integer(i as i64) Value::Integer(i as i64)
} }
@ -38,6 +41,7 @@ impl From<isize> for Value {
#[cfg(feature = "i128_blob")] #[cfg(feature = "i128_blob")]
impl From<i128> for Value { impl From<i128> for Value {
#[inline]
fn from(i: i128) -> Value { fn from(i: i128) -> Value {
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
let mut buf = vec![0u8; 16]; let mut buf = vec![0u8; 16];
@ -50,6 +54,7 @@ impl From<i128> for Value {
#[cfg(feature = "uuid")] #[cfg(feature = "uuid")]
impl From<uuid::Uuid> for Value { impl From<uuid::Uuid> for Value {
#[inline]
fn from(id: uuid::Uuid) -> Value { fn from(id: uuid::Uuid) -> Value {
Value::Blob(id.as_bytes().to_vec()) Value::Blob(id.as_bytes().to_vec())
} }
@ -58,6 +63,7 @@ impl From<uuid::Uuid> for Value {
macro_rules! from_i64( macro_rules! from_i64(
($t:ty) => ( ($t:ty) => (
impl From<$t> for Value { impl From<$t> for Value {
#[inline]
fn from(i: $t) -> Value { fn from(i: $t) -> Value {
Value::Integer(i64::from(i)) Value::Integer(i64::from(i))
} }
@ -73,30 +79,35 @@ from_i64!(u16);
from_i64!(u32); from_i64!(u32);
impl From<i64> for Value { impl From<i64> for Value {
#[inline]
fn from(i: i64) -> Value { fn from(i: i64) -> Value {
Value::Integer(i) Value::Integer(i)
} }
} }
impl From<f32> for Value { impl From<f32> for Value {
#[inline]
fn from(f: f32) -> Value { fn from(f: f32) -> Value {
Value::Real(f.into()) Value::Real(f.into())
} }
} }
impl From<f64> for Value { impl From<f64> for Value {
#[inline]
fn from(f: f64) -> Value { fn from(f: f64) -> Value {
Value::Real(f) Value::Real(f)
} }
} }
impl From<String> for Value { impl From<String> for Value {
#[inline]
fn from(s: String) -> Value { fn from(s: String) -> Value {
Value::Text(s) Value::Text(s)
} }
} }
impl From<Vec<u8>> for Value { impl From<Vec<u8>> for Value {
#[inline]
fn from(v: Vec<u8>) -> Value { fn from(v: Vec<u8>) -> Value {
Value::Blob(v) Value::Blob(v)
} }
@ -106,6 +117,7 @@ impl<T> From<Option<T>> for Value
where where
T: Into<Value>, T: Into<Value>,
{ {
#[inline]
fn from(v: Option<T>) -> Value { fn from(v: Option<T>) -> Value {
match v { match v {
Some(x) => x.into(), Some(x) => x.into(),
@ -116,6 +128,7 @@ where
impl Value { impl Value {
/// Returns SQLite fundamental datatype. /// Returns SQLite fundamental datatype.
#[inline]
pub fn data_type(&self) -> Type { pub fn data_type(&self) -> Type {
match *self { match *self {
Value::Null => Type::Null, Value::Null => Type::Null,

View File

@ -21,6 +21,7 @@ pub enum ValueRef<'a> {
impl ValueRef<'_> { impl ValueRef<'_> {
/// Returns SQLite fundamental datatype. /// Returns SQLite fundamental datatype.
#[inline]
pub fn data_type(&self) -> Type { pub fn data_type(&self) -> Type {
match *self { match *self {
ValueRef::Null => Type::Null, ValueRef::Null => Type::Null,
@ -35,6 +36,7 @@ impl ValueRef<'_> {
impl<'a> ValueRef<'a> { impl<'a> ValueRef<'a> {
/// If `self` is case `Integer`, returns the integral value. Otherwise, /// If `self` is case `Integer`, returns the integral value. Otherwise,
/// returns `Err(Error::InvalidColumnType)`. /// returns `Err(Error::InvalidColumnType)`.
#[inline]
pub fn as_i64(&self) -> FromSqlResult<i64> { pub fn as_i64(&self) -> FromSqlResult<i64> {
match *self { match *self {
ValueRef::Integer(i) => Ok(i), ValueRef::Integer(i) => Ok(i),
@ -44,6 +46,7 @@ impl<'a> ValueRef<'a> {
/// If `self` is case `Real`, returns the floating point value. Otherwise, /// If `self` is case `Real`, returns the floating point value. Otherwise,
/// returns `Err(Error::InvalidColumnType)`. /// returns `Err(Error::InvalidColumnType)`.
#[inline]
pub fn as_f64(&self) -> FromSqlResult<f64> { pub fn as_f64(&self) -> FromSqlResult<f64> {
match *self { match *self {
ValueRef::Real(f) => Ok(f), ValueRef::Real(f) => Ok(f),
@ -53,6 +56,7 @@ impl<'a> ValueRef<'a> {
/// If `self` is case `Text`, returns the string value. Otherwise, returns /// If `self` is case `Text`, returns the string value. Otherwise, returns
/// `Err(Error::InvalidColumnType)`. /// `Err(Error::InvalidColumnType)`.
#[inline]
pub fn as_str(&self) -> FromSqlResult<&'a str> { pub fn as_str(&self) -> FromSqlResult<&'a str> {
match *self { match *self {
ValueRef::Text(t) => { ValueRef::Text(t) => {
@ -64,6 +68,7 @@ impl<'a> ValueRef<'a> {
/// If `self` is case `Blob`, returns the byte slice. Otherwise, returns /// If `self` is case `Blob`, returns the byte slice. Otherwise, returns
/// `Err(Error::InvalidColumnType)`. /// `Err(Error::InvalidColumnType)`.
#[inline]
pub fn as_blob(&self) -> FromSqlResult<&'a [u8]> { pub fn as_blob(&self) -> FromSqlResult<&'a [u8]> {
match *self { match *self {
ValueRef::Blob(b) => Ok(b), ValueRef::Blob(b) => Ok(b),
@ -73,6 +78,7 @@ impl<'a> ValueRef<'a> {
} }
impl From<ValueRef<'_>> for Value { impl From<ValueRef<'_>> for Value {
#[inline]
fn from(borrowed: ValueRef<'_>) -> Value { fn from(borrowed: ValueRef<'_>) -> Value {
match borrowed { match borrowed {
ValueRef::Null => Value::Null, ValueRef::Null => Value::Null,
@ -88,18 +94,21 @@ impl From<ValueRef<'_>> for Value {
} }
impl<'a> From<&'a str> for ValueRef<'a> { impl<'a> From<&'a str> for ValueRef<'a> {
#[inline]
fn from(s: &str) -> ValueRef<'_> { fn from(s: &str) -> ValueRef<'_> {
ValueRef::Text(s.as_bytes()) ValueRef::Text(s.as_bytes())
} }
} }
impl<'a> From<&'a [u8]> for ValueRef<'a> { impl<'a> From<&'a [u8]> for ValueRef<'a> {
#[inline]
fn from(s: &[u8]) -> ValueRef<'_> { fn from(s: &[u8]) -> ValueRef<'_> {
ValueRef::Blob(s) ValueRef::Blob(s)
} }
} }
impl<'a> From<&'a Value> for ValueRef<'a> { impl<'a> From<&'a Value> for ValueRef<'a> {
#[inline]
fn from(value: &'a Value) -> ValueRef<'a> { fn from(value: &'a Value) -> ValueRef<'a> {
match *value { match *value {
Value::Null => ValueRef::Null, Value::Null => ValueRef::Null,
@ -115,6 +124,7 @@ impl<'a, T> From<Option<T>> for ValueRef<'a>
where where
T: Into<ValueRef<'a>>, T: Into<ValueRef<'a>>,
{ {
#[inline]
fn from(s: Option<T>) -> ValueRef<'a> { fn from(s: Option<T>) -> ValueRef<'a> {
match s { match s {
Some(x) => x.into(), Some(x) => x.into(),

View File

@ -155,6 +155,7 @@ fn make_nonnull(v: &str) -> String {
} }
impl Drop for SqliteMallocString { impl Drop for SqliteMallocString {
#[inline]
fn drop(&mut self) { fn drop(&mut self) {
unsafe { ffi::sqlite3_free(self.ptr.as_ptr().cast()) }; unsafe { ffi::sqlite3_free(self.ptr.as_ptr().cast()) };
} }

View File

@ -5,6 +5,7 @@ use std::ffi::CStr;
/// 3.16.2. /// 3.16.2.
/// ///
/// See [`sqlite3_libversion_number()`](https://www.sqlite.org/c3ref/libversion.html). /// See [`sqlite3_libversion_number()`](https://www.sqlite.org/c3ref/libversion.html).
#[inline]
pub fn version_number() -> i32 { pub fn version_number() -> i32 {
unsafe { ffi::sqlite3_libversion_number() } unsafe { ffi::sqlite3_libversion_number() }
} }
@ -12,6 +13,7 @@ pub fn version_number() -> i32 {
/// Returns the SQLite version as a string; e.g., `"3.16.2"` for version 3.16.2. /// Returns the SQLite version as a string; e.g., `"3.16.2"` for version 3.16.2.
/// ///
/// See [`sqlite3_libversion()`](https://www.sqlite.org/c3ref/libversion.html). /// See [`sqlite3_libversion()`](https://www.sqlite.org/c3ref/libversion.html).
#[inline]
pub fn version() -> &'static str { pub fn version() -> &'static str {
let cstr = unsafe { CStr::from_ptr(ffi::sqlite3_libversion()) }; let cstr = unsafe { CStr::from_ptr(ffi::sqlite3_libversion()) };
cstr.to_str() cstr.to_str()

View File

@ -51,6 +51,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 {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> { fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::Array(self.clone())) Ok(ToSqlOutput::Array(self.clone()))
} }

View File

@ -354,6 +354,7 @@ unsafe impl VTabCursor for CSVTabCursor<'_> {
} }
impl From<csv::Error> for Error { impl From<csv::Error> for Error {
#[cold]
fn from(err: csv::Error) -> Error { fn from(err: csv::Error) -> Error {
Error::ModuleError(err.to_string()) Error::ModuleError(err.to_string())
} }

View File

@ -310,6 +310,7 @@ pub struct IndexInfo(*mut ffi::sqlite3_index_info);
impl IndexInfo { impl IndexInfo {
/// Record WHERE clause constraints. /// Record WHERE clause constraints.
#[inline]
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) };
@ -319,6 +320,7 @@ impl IndexInfo {
} }
/// Information about the ORDER BY clause. /// Information about the ORDER BY clause.
#[inline]
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) };
@ -328,11 +330,13 @@ impl IndexInfo {
} }
/// Number of terms in the ORDER BY clause /// Number of terms in the ORDER BY clause
#[inline]
pub fn num_of_order_by(&self) -> usize { pub fn num_of_order_by(&self) -> usize {
unsafe { (*self.0).nOrderBy as usize } unsafe { (*self.0).nOrderBy as usize }
} }
/// Information about what parameters to pass to `VTabCursor.filter`. /// Information about what parameters to pass to `VTabCursor.filter`.
#[inline]
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)
@ -341,6 +345,7 @@ impl IndexInfo {
} }
/// Number used to identify the index /// Number used to identify the index
#[inline]
pub fn set_idx_num(&mut self, idx_num: c_int) { pub fn set_idx_num(&mut self, idx_num: c_int) {
unsafe { unsafe {
(*self.0).idxNum = idx_num; (*self.0).idxNum = idx_num;
@ -348,6 +353,7 @@ impl IndexInfo {
} }
/// True if output is already ordered /// True if output is already ordered
#[inline]
pub fn set_order_by_consumed(&mut self, order_by_consumed: bool) { pub fn set_order_by_consumed(&mut self, order_by_consumed: bool) {
unsafe { unsafe {
(*self.0).orderByConsumed = if order_by_consumed { 1 } else { 0 }; (*self.0).orderByConsumed = if order_by_consumed { 1 } else { 0 };
@ -355,6 +361,7 @@ impl IndexInfo {
} }
/// Estimated cost of using this index /// Estimated cost of using this index
#[inline]
pub fn set_estimated_cost(&mut self, estimated_ost: f64) { pub fn set_estimated_cost(&mut self, estimated_ost: f64) {
unsafe { unsafe {
(*self.0).estimatedCost = estimated_ost; (*self.0).estimatedCost = estimated_ost;
@ -363,6 +370,7 @@ impl IndexInfo {
/// Estimated number of rows returned. /// Estimated number of rows returned.
#[cfg(feature = "modern_sqlite")] // SQLite >= 3.8.2 #[cfg(feature = "modern_sqlite")] // SQLite >= 3.8.2
#[inline]
pub fn set_estimated_rows(&mut self, estimated_rows: i64) { pub fn set_estimated_rows(&mut self, estimated_rows: i64) {
unsafe { unsafe {
(*self.0).estimatedRows = estimated_rows; (*self.0).estimatedRows = estimated_rows;
@ -383,10 +391,12 @@ pub struct IndexConstraintIter<'a> {
impl<'a> Iterator for IndexConstraintIter<'a> { impl<'a> Iterator for IndexConstraintIter<'a> {
type Item = IndexConstraint<'a>; type Item = IndexConstraint<'a>;
#[inline]
fn next(&mut self) -> Option<IndexConstraint<'a>> { fn next(&mut self) -> Option<IndexConstraint<'a>> {
self.iter.next().map(|raw| IndexConstraint(raw)) self.iter.next().map(|raw| IndexConstraint(raw))
} }
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint() self.iter.size_hint()
} }
@ -397,16 +407,19 @@ pub struct IndexConstraint<'a>(&'a ffi::sqlite3_index_constraint);
impl IndexConstraint<'_> { impl IndexConstraint<'_> {
/// Column constrained. -1 for ROWID /// Column constrained. -1 for ROWID
#[inline]
pub fn column(&self) -> c_int { pub fn column(&self) -> c_int {
self.0.iColumn self.0.iColumn
} }
/// Constraint operator /// Constraint operator
#[inline]
pub fn operator(&self) -> IndexConstraintOp { pub fn operator(&self) -> IndexConstraintOp {
IndexConstraintOp::from(self.0.op) IndexConstraintOp::from(self.0.op)
} }
/// True if this constraint is usable /// True if this constraint is usable
#[inline]
pub fn is_usable(&self) -> bool { pub fn is_usable(&self) -> bool {
self.0.usable != 0 self.0.usable != 0
} }
@ -418,11 +431,13 @@ pub struct IndexConstraintUsage<'a>(&'a mut ffi::sqlite3_index_constraint_usage)
impl IndexConstraintUsage<'_> { impl IndexConstraintUsage<'_> {
/// if `argv_index` > 0, constraint is part of argv to `VTabCursor.filter` /// if `argv_index` > 0, constraint is part of argv to `VTabCursor.filter`
#[inline]
pub fn set_argv_index(&mut self, argv_index: c_int) { pub fn set_argv_index(&mut self, argv_index: c_int) {
self.0.argvIndex = argv_index; self.0.argvIndex = argv_index;
} }
/// if `omit`, do not code a test for this constraint /// if `omit`, do not code a test for this constraint
#[inline]
pub fn set_omit(&mut self, omit: bool) { pub fn set_omit(&mut self, omit: bool) {
self.0.omit = if omit { 1 } else { 0 }; self.0.omit = if omit { 1 } else { 0 };
} }
@ -436,10 +451,12 @@ pub struct OrderByIter<'a> {
impl<'a> Iterator for OrderByIter<'a> { impl<'a> Iterator for OrderByIter<'a> {
type Item = OrderBy<'a>; type Item = OrderBy<'a>;
#[inline]
fn next(&mut self) -> Option<OrderBy<'a>> { fn next(&mut self) -> Option<OrderBy<'a>> {
self.iter.next().map(|raw| OrderBy(raw)) self.iter.next().map(|raw| OrderBy(raw))
} }
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint() self.iter.size_hint()
} }
@ -450,11 +467,13 @@ pub struct OrderBy<'a>(&'a ffi::sqlite3_index_info_sqlite3_index_orderby);
impl OrderBy<'_> { impl OrderBy<'_> {
/// Column number /// Column number
#[inline]
pub fn column(&self) -> c_int { pub fn column(&self) -> c_int {
self.0.iColumn self.0.iColumn
} }
/// True for DESC. False for ASC. /// True for DESC. False for ASC.
#[inline]
pub fn is_order_by_desc(&self) -> bool { pub fn is_order_by_desc(&self) -> bool {
self.0.desc != 0 self.0.desc != 0
} }
@ -500,6 +519,7 @@ pub struct Context(*mut ffi::sqlite3_context);
impl Context { impl Context {
/// Set current cell value /// Set current cell value
#[inline]
pub fn set_result<T: ToSql>(&mut self, value: &T) -> Result<()> { pub fn set_result<T: ToSql>(&mut self, value: &T) -> Result<()> {
let t = value.to_sql()?; let t = value.to_sql()?;
unsafe { set_result(self.0, &t) }; unsafe { set_result(self.0, &t) };
@ -517,11 +537,13 @@ pub struct Values<'a> {
impl Values<'_> { impl Values<'_> {
/// Returns the number of values. /// Returns the number of values.
#[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.args.len() self.args.len()
} }
/// Returns `true` if there is no value. /// Returns `true` if there is no value.
#[inline]
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.args.is_empty() self.args.is_empty()
} }
@ -567,6 +589,7 @@ impl Values<'_> {
} }
/// Turns `Values` into an iterator. /// Turns `Values` into an iterator.
#[inline]
pub fn iter(&self) -> ValueIter<'_> { pub fn iter(&self) -> ValueIter<'_> {
ValueIter { ValueIter {
iter: self.args.iter(), iter: self.args.iter(),
@ -578,6 +601,7 @@ impl<'a> IntoIterator for &'a Values<'a> {
type IntoIter = ValueIter<'a>; type IntoIter = ValueIter<'a>;
type Item = ValueRef<'a>; type Item = ValueRef<'a>;
#[inline]
fn into_iter(self) -> ValueIter<'a> { fn into_iter(self) -> ValueIter<'a> {
self.iter() self.iter()
} }
@ -591,12 +615,14 @@ pub struct ValueIter<'a> {
impl<'a> Iterator for ValueIter<'a> { impl<'a> Iterator for ValueIter<'a> {
type Item = ValueRef<'a>; type Item = ValueRef<'a>;
#[inline]
fn next(&mut self) -> Option<ValueRef<'a>> { fn next(&mut self) -> Option<ValueRef<'a>> {
self.iter self.iter
.next() .next()
.map(|&raw| unsafe { ValueRef::from_value(raw) }) .map(|&raw| unsafe { ValueRef::from_value(raw) })
} }
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint() self.iter.size_hint()
} }
@ -607,6 +633,7 @@ impl Connection {
/// ///
/// Step 3 of [Creating New Virtual Table /// Step 3 of [Creating New Virtual Table
/// Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations). /// Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
#[inline]
pub fn create_module<'vtab, T: VTab<'vtab>>( pub fn create_module<'vtab, T: VTab<'vtab>>(
&self, &self,
module_name: &str, module_name: &str,
@ -977,6 +1004,7 @@ where
/// Virtual table cursors can set an error message by assigning a string to /// Virtual table cursors can set an error message by assigning a string to
/// `zErrMsg`. /// `zErrMsg`.
#[cold]
unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor, result: Result<T>) -> c_int { unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor, result: Result<T>) -> c_int {
match result { match result {
Ok(_) => ffi::SQLITE_OK, Ok(_) => ffi::SQLITE_OK,
@ -995,6 +1023,7 @@ unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor, result: Result<
/// Virtual tables methods can set an error message by assigning a string to /// Virtual tables methods can set an error message by assigning a string to
/// `zErrMsg`. /// `zErrMsg`.
#[cold]
unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) { unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) {
if !(*vtab).zErrMsg.is_null() { if !(*vtab).zErrMsg.is_null() {
ffi::sqlite3_free((*vtab).zErrMsg as *mut c_void); ffi::sqlite3_free((*vtab).zErrMsg as *mut c_void);
@ -1004,6 +1033,7 @@ unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) {
/// To raise an error, the `column` method should use this method to set the /// To raise an error, the `column` method should use this method to set the
/// error message and return the error code. /// error message and return the error code.
#[cold]
unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) -> c_int { unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) -> c_int {
match result { match result {
Ok(_) => ffi::SQLITE_OK, Ok(_) => ffi::SQLITE_OK,