diff options
author | Teddy Wing | 2022-04-02 20:35:28 +0200 |
---|---|---|
committer | Teddy Wing | 2022-04-02 20:35:28 +0200 |
commit | bc0afe2353f925124c67bf5785813432de44af57 (patch) | |
tree | 7c4d12048af856fe7884d6a678fc13916d0472d5 /src/yaml.rs | |
parent | 02bc0d184fa60668bafe8de5ba844d132aa2ffb3 (diff) | |
download | yaqlite-bc0afe2353f925124c67bf5785813432de44af57.tar.bz2 |
Add a SQL update function to update a record from YAML
Add a new `db_update()` function to update an existing database record
from a YAML hash.
Had a little trouble building up the params for the prepared SQL
statement but finally managed to set up the types correctly and include
the record ID to update. Thanks to this Stack Overflow answer by
Shepmaster (https://stackoverflow.com/users/155423/shepmaster) for
pointing me in the right direction:
https://stackoverflow.com/questions/46624591/cannot-call-rusqlites-query-because-it-expects-the-type-rusqlitetypestos/46625932#46625932
Diffstat (limited to 'src/yaml.rs')
-rw-r--r-- | src/yaml.rs | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/yaml.rs b/src/yaml.rs index acf1a9e..d1108f1 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -74,6 +74,78 @@ pub fn db_insert( ) } +/// TODO +pub fn db_update( + doc: &mut yaml::Yaml, + tx: &rusqlite::Transaction, + table_name: &str, + table_columns: &HashSet<String>, + primary_key_column: &str, + record_id: &str, +) -> Result<(), crate::Error> { + with_hash( + doc, + &mut |hash| { + use std::borrow::Cow; + + hash_filter_table_columns(hash, &table_columns); + + let mut stmt = tx.prepare( + &format!( + r#" + UPDATE "{}" + SET + {} + WHERE {} = ?; + "#, + table_name, + + // List of: + // "column_name" = ?, + // "column_name" = ? + hash.keys() + .map(|k| k.as_str()) + .filter(|k| k.is_some()) + + // Always `Some`. + .map(|k| format!(r#""{}" = ?"#, k.unwrap())) + .collect::<Vec<String>>() + .join(", "), + + primary_key_column, + ), + )?; + + // TODO: convert to &[&dyn ToSql] ? + // let values = hash.values().map(|v| Yaml(Cow::Borrowed(v))); + // values.push(primary_key); + // stmt.execute(rusqlite::params_from_iter(values))?; + + // let values: Vec<&dyn rusqlite::ToSql>; + // + // for v in hash.values() { + // values.push(&Yaml(Cow::Borrowed(v))); + // } + // + // stmt.execute(values)?; + + // let values: dyn Iterator<Item = &dyn rusqlite::ToSql> = hash.values(); + // values = values.map(|v| Yaml(Cow::Borrowed(v))); + // values.chain(&[&primary_key]); + // stmt.execute(rusqlite::params_from_iter(values))?; + + let mut values: Vec<_> = hash.values() + .map(|v| Yaml(Cow::Borrowed(v))) + .map(|v| Box::new(v) as Box<dyn rusqlite::ToSql>) + .collect(); + values.push(Box::new(record_id)); + stmt.execute(rusqlite::params_from_iter(values))?; + + Ok(()) + } + ) +} + /// Parse a YAML document and run a function for all hashes in the document. fn with_hash<F>( doc: &mut yaml::Yaml, |