mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 13:58:55 +08:00 
			
		
		
		
	Update documentation
This commit is contained in:
		| @@ -187,7 +187,7 @@ macro_rules! params { | ||||
| /// } | ||||
| /// | ||||
| /// fn add_person(conn: &Connection, person: &Person) -> Result<()> { | ||||
| ///     conn.execute_named( | ||||
| ///     conn.execute( | ||||
| ///         "INSERT INTO person (name, age_in_years, data) | ||||
| ///          VALUES (:name, :age, :data)", | ||||
| ///         named_params!{ | ||||
| @@ -511,7 +511,7 @@ impl Connection { | ||||
|     /// ```rust,no_run | ||||
|     /// # use rusqlite::{Connection, Result}; | ||||
|     /// fn insert(conn: &Connection) -> Result<usize> { | ||||
|     ///     conn.execute_named( | ||||
|     ///     conn.execute( | ||||
|     ///         "INSERT INTO test (name) VALUES (:name)", | ||||
|     ///         rusqlite::named_params!{ ":name": "one" }, | ||||
|     ///     ) | ||||
|   | ||||
							
								
								
									
										172
									
								
								src/params.rs
									
									
									
									
									
								
							
							
						
						
									
										172
									
								
								src/params.rs
									
									
									
									
									
								
							| @@ -5,16 +5,162 @@ mod sealed { | ||||
|     /// that are allowed are ones in this crate. | ||||
|     pub trait Sealed {} | ||||
| } | ||||
| // must not be `pub use`. | ||||
| use sealed::Sealed; | ||||
|  | ||||
| /// Trait used for parameter sets passed into SQL statements/queries. | ||||
| /// Trait used for [sets of parameter][params] passed into SQL | ||||
| /// statements/queries. | ||||
| /// | ||||
| /// Currently, this trait can only be implemented inside this crate. | ||||
| /// [params]: https://www.sqlite.org/c3ref/bind_blob.html | ||||
| /// | ||||
| /// Note: Currently, this trait can only be implemented inside this crate. | ||||
| /// Additionally, it's methods (which are `doc(hidden)`) should currently not be | ||||
| /// considered part of the stable API, although it's possible they will | ||||
| /// stabilize in the future. | ||||
| /// | ||||
| /// # Passing parameters to SQLite | ||||
| /// | ||||
| /// Many functions in this library let you pass parameters to SQLite. Doing this | ||||
| /// lets you avoid any risk of SQL injection, and is simpler than escaping | ||||
| /// things manually. Aside from deprecated functions and a few helpers, this is | ||||
| /// indicated by the function taking a generic argument that implements `Params` | ||||
| /// (this trait). | ||||
| /// | ||||
| /// ## Positional parameters | ||||
| /// | ||||
| /// For cases where you want to pass a list of parameters where the number of | ||||
| /// parameters is known at compile time, this can be done in one of the | ||||
| /// following ways: | ||||
| /// | ||||
| /// - Using the [`rusqlite::params!`](crate::params!) macro, e.g. | ||||
| ///   `thing.query(rusqlite::params![1, "foo", bar])`. This is mostly useful for | ||||
| ///   heterogeneous lists of parameters, or lists where the number of parameters | ||||
| ///   exceeds 32. | ||||
| /// | ||||
| /// - For small heterogeneous lists of parameters, they can either be passed as: | ||||
| /// | ||||
| ///     - an array, as in `thing.query([1i32, 2, 3, 4])` or `thing.query(["foo", | ||||
| ///       "bar", "baz"])`. | ||||
| /// | ||||
| ///     - a reference to an array of references, as in `thing.query(&["foo", | ||||
| ///       "bar", "baz"])` or `thing.query(&[&1i32, &2, &3])`. | ||||
| /// | ||||
| ///         (Note: in this case we don't implement this for slices for coherence | ||||
| ///         reasons, so it really is only for the "reference to array" types — | ||||
| ///         hence why the number of parameters must be <= 32 or you need to | ||||
| ///         reach for `rusqlite::params!`) | ||||
| /// | ||||
| ///     Unfortunately, in the current design it's not possible to allow this for | ||||
| ///     references to arrays of non-references (e.g. `&[1i32, 2, 3]`). Code like | ||||
| ///     this should instead either use `params!`, an array literal, a `&[&dyn | ||||
| ///     ToSql]` or if none of those work, [`ParamsFromIter`]. | ||||
| /// | ||||
| /// - As a slice of `ToSql` trait object references, e.g. `&[&dyn ToSql]`. This | ||||
| ///   is mostly useful for passing parameter lists around as arguments without | ||||
| ///   having every function take a generic `P: Params`. | ||||
| /// | ||||
| /// ### Example (positional) | ||||
| /// | ||||
| /// ```rust,no_run | ||||
| /// # use rusqlite::{Connection, Result, params}; | ||||
| /// fn update_rows(conn: &Connection) -> Result<()> { | ||||
| ///     let mut stmt = conn.prepare("INSERT INTO test (a, b) VALUES (?, ?)")?; | ||||
| /// | ||||
| ///     // Using `rusqlite::params!`: | ||||
| ///     stmt.execute(params![1i32, "blah"])?; | ||||
| /// | ||||
| ///     // array literal — non-references | ||||
| ///     stmt.execute([2i32, 3i32])?; | ||||
| /// | ||||
| ///     // array literal — references | ||||
| ///     stmt.execute(["foo", "bar"])?; | ||||
| /// | ||||
| ///     // Slice literal, references: | ||||
| ///     stmt.execute(&[&2i32, &3i32])?; | ||||
| /// | ||||
| ///     // Note: The types behind the references don't have to be `Sized` | ||||
| ///     stmt.execute(&["foo", "bar"])?; | ||||
| /// | ||||
| ///     // However, this doesn't work (see above): | ||||
| ///     // stmt.execute(&[1i32, 2i32])?; | ||||
| ///     Ok(()) | ||||
| /// } | ||||
| /// ``` | ||||
| /// | ||||
| /// ## Named parameters | ||||
| /// | ||||
| /// SQLite lets you name parameters using a number of conventions (":foo", | ||||
| /// "@foo", "$foo"). You can pass named parameters in to SQLite using rusqlite | ||||
| /// in a few ways: | ||||
| /// | ||||
| /// - Using the [`rusqlite::named_params!`](crate::named_params!) macro, as in | ||||
| ///   `stmt.execute(named_params!{ ":name": "foo", ":age": 99 })`. Similar to | ||||
| ///   the `params` macro, this is most useful for heterogeneous lists of | ||||
| ///   parameters, or lists where the number of parameters exceeds 32. | ||||
| /// | ||||
| /// - As a slice of `&[(&str, &dyn ToSql)]`. This is what essentially all of | ||||
| ///   these boil down to in the end, conceptually at least. In theory you can | ||||
| ///   pass this as `stmt. | ||||
| /// | ||||
| /// - As array references, similar to the positional params. This looks like | ||||
| ///   `thing.query(&[(":foo", &1i32), (":bar", &2i32)])` or | ||||
| ///   `thing.query(&[(":foo", "abc"), (":bar", "def")])`. | ||||
| /// | ||||
| /// Note: Unbound named parameters will be left to the value they previously | ||||
| /// were bound with, falling back to `NULL` for parameters which have never been | ||||
| /// bound. | ||||
| /// | ||||
| /// ### Example (named) | ||||
| /// | ||||
| /// ```rust,no_run | ||||
| /// # use rusqlite::{Connection, Result, named_params}; | ||||
| /// fn insert(conn: &Connection) -> Result<()> { | ||||
| ///     let mut stmt = conn.prepare("INSERT INTO test (key, value) VALUES (:key, :value)")?; | ||||
| ///     // Using `rusqlite::params!`: | ||||
| ///     stmt.execute(named_params!{ ":key": "one", ":val": 2 })?; | ||||
| ///     // Alternatively: | ||||
| ///     stmt.execute(&[(":key", "three"), (":val", "four")])?; | ||||
| ///     // Or: | ||||
| ///     stmt.execute(&[(":key", &100), (":val", &200)])?; | ||||
| ///     Ok(()) | ||||
| /// } | ||||
| /// ``` | ||||
| /// | ||||
| /// ## No parameters | ||||
| /// | ||||
| /// You can just use an empty array literal for no params. The | ||||
| /// `rusqlite::NO_PARAMS` constant which was so common in previous versions of | ||||
| /// this library is no longer needed. | ||||
| /// | ||||
| /// ### Example (no parameters) | ||||
| /// | ||||
| /// ```rust,no_run | ||||
| /// # use rusqlite::{Connection, Result, params}; | ||||
| /// fn delete_all_users(conn: &Connection) -> Result<()> { | ||||
| ///     // Just use an empty array (e.g. `[]`) for no params. | ||||
| ///     conn.execute("DELETE FROM users", [])?; | ||||
| ///     Ok(()) | ||||
| /// } | ||||
| /// ``` | ||||
| /// | ||||
| /// ## Dynamic parameter list | ||||
| /// | ||||
| /// If you have a number of parameters which is unknown at compile time (for | ||||
| /// example, building a dynamic query at runtime), you have two choices: | ||||
| /// | ||||
| /// - Use a `&[&dyn ToSql]`, which is nice if you have one otherwise might be | ||||
| ///   annoying. | ||||
| /// - Use the [`ParamsFromIter`] type. This essentially lets you wrap an | ||||
| ///   iterator some `T: ToSql` with something that implements `Params`. | ||||
| /// | ||||
| /// A lot of the considerations here are similar either way, so you should see | ||||
| /// the [`ParamsFromIter`] documentation for more info / examples. | ||||
| pub trait Params: Sealed { | ||||
|     /// Binds the parameters to the statement. It is unlikely calling this | ||||
|     /// explicitly will do what you want. Please use `Statement::query` or | ||||
|     /// similar directly. | ||||
|     // XXX not public api, might not need to expose. | ||||
|     // | ||||
|     // Binds the parameters to the statement. It is unlikely calling this | ||||
|     // explicitly will do what you want. Please use `Statement::query` or | ||||
|     // similar directly. | ||||
|     // | ||||
|     // For now, just hide the function in the docs... | ||||
|     #[doc(hidden)] | ||||
|     fn bind_in(self, stmt: &mut Statement<'_>) -> Result<()>; | ||||
| @@ -69,6 +215,10 @@ macro_rules! impl_for_array_ref { | ||||
|         } | ||||
|     )+}; | ||||
| } | ||||
|  | ||||
| // Following libstd/libcore's (old) lead, implement this for arrays up to `[_; | ||||
| // 32]`. Note `[_; 0]` is intentionally omitted for coherence reasons, see the | ||||
| // note above the impl of `[&dyn ToSql; 0]` for more information. | ||||
| impl_for_array_ref!( | ||||
|     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ||||
|     18 19 20 21 22 23 24 25 26 27 29 30 31 32 | ||||
| @@ -154,17 +304,21 @@ impl_for_array_ref!( | ||||
| /// production-ready: | ||||
| /// | ||||
| /// - production code should ensure `usernames` isn't so large that it will | ||||
| ///   surpass [`conn.limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER)`][limits]) | ||||
| ///   (chunking if too large). | ||||
| ///   surpass [`conn.limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER)`][limits]), | ||||
| ///   chunking if too large. (Note that the limits api requires rusqlite to have | ||||
| ///   the "limits" feature). | ||||
| /// | ||||
| /// - `repeat_vars` can be implemented in a way that avoids needing to allocate | ||||
| ///   a String. | ||||
| /// | ||||
| /// - Etc... | ||||
| /// | ||||
| /// [limits]: crate::Connection::limit | ||||
| /// | ||||
| /// This complexity reflects the fact that `ParamsFromIter` is mainly intended | ||||
| /// for advanced use cases — most of the time you should know how many | ||||
| /// parameters you have statically. | ||||
| /// parameters you have statically (and if you don't, you're either doing | ||||
| /// something tricky, or should take a moment to think about the design). | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct ParamsFromIter<I>(I); | ||||
|  | ||||
|   | ||||
| @@ -34,11 +34,14 @@ impl Statement<'_> { | ||||
|     /// # use rusqlite::{Connection, Result, params}; | ||||
|     /// fn update_rows(conn: &Connection) -> Result<()> { | ||||
|     ///     let mut stmt = conn.prepare("UPDATE foo SET bar = 'baz' WHERE qux = ?")?; | ||||
|     /// | ||||
|     ///     // The `rusqlite::params!` macro is mostly useful when the parameters do not | ||||
|     ///     // all have the same type, or if there are more than 32 parameters | ||||
|     ///     // at once. | ||||
|     ///     stmt.execute(params![1i32])?; | ||||
|     ///     // Similarly... | ||||
|     ///     // However, it's not required, many cases are fine as: | ||||
|     ///     stmt.execute(&[&2i32])?; | ||||
|     /// | ||||
|     ///     // Or even: | ||||
|     ///     stmt.execute([2i32])?; | ||||
|     ///     Ok(()) | ||||
|     /// } | ||||
|     /// ``` | ||||
| @@ -46,21 +49,18 @@ impl Statement<'_> { | ||||
|     /// ### Use with named parameters | ||||
|     /// | ||||
|     /// ```rust,no_run | ||||
|     /// # use rusqlite::{Connection, Result}; | ||||
|     /// fn insert(conn: &Connection) -> Result<usize> { | ||||
|     ///     let mut stmt = conn.prepare("INSERT INTO test (name) VALUES (:name)")?; | ||||
|     ///     stmt.execute(&[(":name", &"one")]) | ||||
|     /// } | ||||
|     /// ``` | ||||
|     /// | ||||
|     /// 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_params!{":name": "one"}) | ||||
|     /// fn insert(conn: &Connection) -> Result<()> { | ||||
|     ///     let mut stmt = conn.prepare("INSERT INTO test (key, value) VALUES (:key, :value)")?; | ||||
|     ///     // The `rusqlite::named_params!` macro (like `params!`) is useful for heterogeneous | ||||
|     ///     // sets of parameters (where all parameters are not the same type), or for queries | ||||
|     ///     // with many (more than 32) statically known parameters. | ||||
|     ///     stmt.execute(named_params!{ ":key": "one", ":val": 2 })?; | ||||
|     ///     // However, named parameters can also be passed like: | ||||
|     ///     stmt.execute(&[(":key", "three"), (":val", "four")])?; | ||||
|     ///     // Or even: (note that a &T is required for the value type, currently) | ||||
|     ///     stmt.execute(&[(":key", &100), (":val", &200)])?; | ||||
|     ///     Ok(()) | ||||
|     /// } | ||||
|     /// ``` | ||||
|     /// | ||||
|   | ||||
		Reference in New Issue
	
	Block a user