aboutsummaryrefslogtreecommitdiffstats
path: root/src/yaml.rs
diff options
context:
space:
mode:
authorTeddy Wing2022-04-02 20:35:28 +0200
committerTeddy Wing2022-04-02 20:35:28 +0200
commitbc0afe2353f925124c67bf5785813432de44af57 (patch)
tree7c4d12048af856fe7884d6a678fc13916d0472d5 /src/yaml.rs
parent02bc0d184fa60668bafe8de5ba844d132aa2ffb3 (diff)
downloadyaqlite-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.rs72
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,