//! # ConcatSQL
//!
//! `concatsql` is a secure library for PostgreSQL, MySQL and SQLite.
//! Unlike other libraries, you can use string concatenation to prevent SQL injection.
//!
//! ```rust
//! use concatsql::prelude::*;
//!
//! fn main() {
//! let conn = concatsql::sqlite::open(":memory:").unwrap();
//! conn.execute(r#"
//! CREATE TABLE users (name TEXT, age INTEGER);
//! INSERT INTO users (name, age) VALUES ('Alice', 42);
//! INSERT INTO users (name, age) VALUES ('Bob', 69);
//! "#).unwrap();
//!
//! let age = String::from("42"); // user input
//! let sql = prep("SELECT name FROM users WHERE age = ") + &age;
//! // At runtime it will be transformed into a query like
//! assert_eq!(sql.simulate(), "SELECT name FROM users WHERE age = '42'");
//! for row in conn.rows(&sql).unwrap() {
//! assert_eq!(row.get(0).unwrap(), "Alice");
//! assert_eq!(row.get("name").unwrap(), "Alice");
//! }
//!
//! let age = String::from("42 OR 1=1; --"); // user input
//! let sql = prep("SELECT name FROM users WHERE age = ") + &age;
//! // At runtime it will be transformed into a query like
//! assert_eq!(sql.simulate(), "SELECT name FROM users WHERE age = '42 OR 1=1; --'");
//! conn.iterate(&sql, |_| { unreachable!() }).unwrap();
//! }
//! ```
pub use crate;
pub use crate;
pub use crate;
pub use crate;
pub use crate;
pub use crate;
/// A typedef of the result returned by many methods.
pub type Result<T, E = crate Error> = Result;
/// Prepare a SQL statement for execution.
///
/// # Examples
///
/// ```
/// use concatsql::prep;
/// # let conn = concatsql::sqlite::open(":memory:").unwrap();
/// # let stmt = prep!(r#"CREATE TABLE users (name TEXT, id INTEGER);
/// # INSERT INTO users (name, id) VALUES ('Alice', 42);
/// # INSERT INTO users (name, id) VALUES ('Bob', 69);"#);
/// # conn.execute(stmt).unwrap();
/// for name in ["Alice", "Bob"].iter() {
/// let stmt = prep!("INSERT INTO users (name) VALUES (") + name + prep!(")");
/// conn.execute(stmt).unwrap();
/// }
/// ```
///
/// # Failure
///
/// If you take a value other than `&'static str` as an argument, it will fail.
///
/// ```compile_fail
/// # use concatsql::prelude::*;
/// let passwd = String::from("'' or 1=1; --");
/// prep!("SELECT * FROM users WHERE passwd=") + prep!(&passwd); // shouldn't compile!
/// ```
///
/// # Safety
///
/// ```
/// # use concatsql::prelude::*;
/// prep!("SELECT * FROM users WHERE id=") + 42;
/// prep!("INSERT INTO msg VALUES ('I''m cat.')");
/// prep!("INSERT INTO msg VALUES (\"I'm cat.\")");
/// prep!("INSERT INTO msg VALUES (") + "I'm cat." + prep!(")");
/// ```
/// Prepare a SQL statement for execution.
///
/// # Examples
///
/// ```
/// use concatsql::prep;
/// # let conn = concatsql::sqlite::open(":memory:").unwrap();
/// # let stmt = prep!(r#"CREATE TABLE users (name TEXT, id INTEGER);
/// # INSERT INTO users (name, id) VALUES ('Alice', 42);
/// # INSERT INTO users (name, id) VALUES ('Bob', 69);"#);
/// # conn.execute(stmt).unwrap();
/// for name in ["Alice", "Bob"].iter() {
/// let stmt = prep("INSERT INTO users (name) VALUES (") + name + prep(")");
/// conn.execute(stmt).unwrap();
/// }
/// ```
///
/// # Failure
///
/// If you take a value other than `&'static str` as an argument, it will fail.
///
/// ```compile_fail
/// # use concatsql::prelude::*;
/// let passwd = String::from("'' or 1=1; --");
/// prep("SELECT * FROM users WHERE passwd=") + prep(&passwd); // shouldn't compile!
/// ```
///
/// # Safety
///
/// ```
/// # use concatsql::prelude::*;
/// prep("SELECT * FROM users WHERE id=") + 42;
/// prep("INSERT INTO msg VALUES ('I''m cat.')");
/// prep("INSERT INTO msg VALUES (\"I'm cat.\")");
/// prep("INSERT INTO msg VALUES (") + "I'm cat." + prep(")");
/// ```
/// A macro making it more convenient to pass heterogeneous lists
/// of parameters as a `&[&dyn ToValue]`.
///
/// # Example
///
/// ```
/// # use concatsql::prelude::*;
/// let sql = prep("VALUES(") + params![42i32,"Alice"] + prep(")");
/// assert_eq!(sql.simulate(), "VALUES(42,'Alice')");
/// ```