mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-26 19:41:37 +08:00
Merge pull request #471 from thomcc/params-macro
Add params/named_params macro, and expose ToSql from top level
This commit is contained in:
commit
6e0b1e2751
87
src/lib.rs
87
src/lib.rs
@ -6,7 +6,7 @@
|
|||||||
//! extern crate time;
|
//! extern crate time;
|
||||||
//!
|
//!
|
||||||
//! use rusqlite::types::ToSql;
|
//! use rusqlite::types::ToSql;
|
||||||
//! use rusqlite::{Connection, NO_PARAMS};
|
//! use rusqlite::{Connection, params};
|
||||||
//! use time::Timespec;
|
//! use time::Timespec;
|
||||||
//!
|
//!
|
||||||
//! #[derive(Debug)]
|
//! #[derive(Debug)]
|
||||||
@ -27,7 +27,7 @@
|
|||||||
//! time_created TEXT NOT NULL,
|
//! time_created TEXT NOT NULL,
|
||||||
//! data BLOB
|
//! data BLOB
|
||||||
//! )",
|
//! )",
|
||||||
//! NO_PARAMS,
|
//! params![],
|
||||||
//! )
|
//! )
|
||||||
//! .unwrap();
|
//! .unwrap();
|
||||||
//! let me = Person {
|
//! let me = Person {
|
||||||
@ -39,7 +39,7 @@
|
|||||||
//! conn.execute(
|
//! conn.execute(
|
||||||
//! "INSERT INTO person (name, time_created, data)
|
//! "INSERT INTO person (name, time_created, data)
|
||||||
//! VALUES (?1, ?2, ?3)",
|
//! VALUES (?1, ?2, ?3)",
|
||||||
//! &[&me.name as &ToSql, &me.time_created, &me.data],
|
//! params![me.name, me.time_created, me.data],
|
||||||
//! )
|
//! )
|
||||||
//! .unwrap();
|
//! .unwrap();
|
||||||
//!
|
//!
|
||||||
@ -47,7 +47,7 @@
|
|||||||
//! .prepare("SELECT id, name, time_created, data FROM person")
|
//! .prepare("SELECT id, name, time_created, data FROM person")
|
||||||
//! .unwrap();
|
//! .unwrap();
|
||||||
//! let person_iter = stmt
|
//! let person_iter = stmt
|
||||||
//! .query_map(NO_PARAMS, |row| Person {
|
//! .query_map(params![], |row| Person {
|
||||||
//! id: row.get(0),
|
//! id: row.get(0),
|
||||||
//! name: row.get(1),
|
//! name: row.get(1),
|
||||||
//! time_created: row.get(2),
|
//! time_created: row.get(2),
|
||||||
@ -88,7 +88,9 @@ use std::sync::{Arc, Mutex, Once, ONCE_INIT};
|
|||||||
use crate::cache::StatementCache;
|
use crate::cache::StatementCache;
|
||||||
use crate::error::{error_from_handle, error_from_sqlite_code};
|
use crate::error::{error_from_handle, error_from_sqlite_code};
|
||||||
use crate::raw_statement::RawStatement;
|
use crate::raw_statement::RawStatement;
|
||||||
use crate::types::{ToSql, ValueRef};
|
use crate::types::ValueRef;
|
||||||
|
|
||||||
|
pub use crate::types::ToSql;
|
||||||
|
|
||||||
pub use crate::statement::{Statement, StatementStatus};
|
pub use crate::statement::{Statement, StatementStatus};
|
||||||
|
|
||||||
@ -144,6 +146,77 @@ const STATEMENT_CACHE_DEFAULT_CAPACITY: usize = 16;
|
|||||||
/// To be used when your statement has no [parameter](https://sqlite.org/lang_expr.html#varparam).
|
/// To be used when your statement has no [parameter](https://sqlite.org/lang_expr.html#varparam).
|
||||||
pub const NO_PARAMS: &[&dyn ToSql] = &[];
|
pub const NO_PARAMS: &[&dyn ToSql] = &[];
|
||||||
|
|
||||||
|
|
||||||
|
/// A macro making it more convenient to pass heterogeneous lists
|
||||||
|
/// of parameters as a `&[&dyn ToSql]`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// # use rusqlite::{Result, Connection, params};
|
||||||
|
///
|
||||||
|
/// struct Person {
|
||||||
|
/// name: String,
|
||||||
|
/// age_in_years: u8,
|
||||||
|
/// data: Option<Vec<u8>>,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn add_person(conn: &Connection, person: &Person) -> Result<()> {
|
||||||
|
/// conn.execute("INSERT INTO person (name, age_in_years, data)
|
||||||
|
/// VALUES (?1, ?2, ?3)",
|
||||||
|
/// params![person.name, person.age_in_years, person.data])?;
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! params {
|
||||||
|
() => {
|
||||||
|
$crate::NO_PARAMS
|
||||||
|
};
|
||||||
|
($($param:expr),+ $(,)?) => {
|
||||||
|
&[$(&$param as &dyn $crate::ToSql),+]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A macro making it more convenient to pass lists of named parameters
|
||||||
|
/// as a `&[(&str, &dyn ToSql)]`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// # use rusqlite::{Result, Connection, named_params};
|
||||||
|
///
|
||||||
|
/// struct Person {
|
||||||
|
/// name: String,
|
||||||
|
/// age_in_years: u8,
|
||||||
|
/// data: Option<Vec<u8>>,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn add_person(conn: &Connection, person: &Person) -> Result<()> {
|
||||||
|
/// conn.execute_named(
|
||||||
|
/// "INSERT INTO person (name, age_in_years, data)
|
||||||
|
/// VALUES (:name, :age, :data)",
|
||||||
|
/// named_params!{
|
||||||
|
/// ":name": person.name,
|
||||||
|
/// ":age": person.age_in_years,
|
||||||
|
/// ":data": person.data,
|
||||||
|
/// }
|
||||||
|
/// )?;
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! named_params {
|
||||||
|
() => {
|
||||||
|
&[]
|
||||||
|
};
|
||||||
|
// Note: It's a lot more work to support this as part of the same macro as
|
||||||
|
// `params!`, unfortunately.
|
||||||
|
($($param_name:literal: $param_val:expr),+ $(,)?) => {
|
||||||
|
&[$(($param_name, &$param_val as &dyn $crate::ToSql)),+]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// A typedef of the result returned by many methods.
|
/// A typedef of the result returned by many methods.
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
@ -1644,7 +1717,7 @@ mod test {
|
|||||||
let i_to_insert = i as i64;
|
let i_to_insert = i as i64;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
insert_stmt
|
insert_stmt
|
||||||
.execute(&[&i_to_insert as &dyn ToSql, &v])
|
.execute(params![i_to_insert, v])
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
@ -1902,7 +1975,7 @@ mod test {
|
|||||||
END;";
|
END;";
|
||||||
db.execute_batch(sql).unwrap();
|
db.execute_batch(sql).unwrap();
|
||||||
|
|
||||||
db.query_row("SELECT * FROM foo", NO_PARAMS, |r| {
|
db.query_row("SELECT * FROM foo", params![], |r| {
|
||||||
assert_eq!(2, r.column_count())
|
assert_eq!(2, r.column_count())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -112,6 +112,17 @@ impl<'conn> Statement<'conn> {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Note, the `named_params` macro is provided for syntactic convenience, and
|
||||||
|
/// so the above example could also be written as:
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// # use rusqlite::{Connection, Result, named_params};
|
||||||
|
/// fn insert(conn: &Connection) -> Result<usize> {
|
||||||
|
/// let mut stmt = conn.prepare("INSERT INTO test (name) VALUES (:name)")?;
|
||||||
|
/// stmt.execute_named(named_params!{":name": "one"})
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if binding parameters fails, the executed statement
|
/// Will return `Err` if binding parameters fails, the executed statement
|
||||||
@ -205,6 +216,21 @@ impl<'conn> Statement<'conn> {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Note, the `named_params!` macro is provided for syntactic convenience, and
|
||||||
|
/// so the above example could also be written as:
|
||||||
|
///
|
||||||
|
/// ```rust,no_run
|
||||||
|
/// # use rusqlite::{Connection, Result, named_params};
|
||||||
|
/// fn query(conn: &Connection) -> Result<()> {
|
||||||
|
/// let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?;
|
||||||
|
/// let mut rows = stmt.query_named(named_params!{ ":name": "one" })?;
|
||||||
|
/// while let Some(row) = rows.next() {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// # Failure
|
/// # Failure
|
||||||
///
|
///
|
||||||
/// Will return `Err` if binding parameters fails.
|
/// Will return `Err` if binding parameters fails.
|
||||||
|
Loading…
Reference in New Issue
Block a user