fixed up, because upsert fails for rquired key

This commit is contained in:
Brandon Thomas committed 2022-02-26 06:38:55 -05:00
1 parent e738d147e4
commit 9633e7515a
1 file changed
+51 -17
@@ -1,5 +1,6 @@
use anyhow::anyhow;
use container_common::anyhow_result::AnyhowResult;
use log::error;
use once_cell::sync::Lazy;
use regex::Regex;
use sqlx::MySqlPool;
@@ -32,30 +33,63 @@ pub async fn reorder_twitch_event_rules(
check_token_safety(rule_token.as_str())?;
}
// THIS IS NOT SANITIZED, so we check for injection here.
check_token_safety(user_token)?;
let query_inner = rule_token_to_order_map.iter()
.map(|(token, position)| {
format!("(\"{}\", {}, \"{}\")", token.as_str(), position, ip_address_update)
// NB: Sadly upserts fail due to other required primary keys that we cannot supply here (eg. uuid).
// let query_inner = rule_token_to_order_map.iter()
// .map(|(token, position)| {
// format!("(\"{}\", {}, \"{}\")", token.as_str(), position, ip_address_update)
// })
// .collect::<Vec<String>>()
// .join(", ");
//
// // Upsert to accomplish multiple updates at once.
// // tl;dr https://stackoverflow.com/a/34866431
// // ALSO THIS IS NOT SANITIZED.
// let query = format!(r#"
//INSERT INTO twitch_event_rules (token, user_specified_rule_order, ip_address_last_update)
//VALUES
// {}
//ON DUPLICATE KEY UPDATE
// token=VALUES(token),
// user_specified_rule_order=VALUES(user_specified_rule_order),
// ip_address_last_update=VALUES(ip_address_last_update)
// "#, query_inner);
let rule_tokens = rule_token_to_order_map.iter()
.map(|(token, _position)| {
format!("'{}'", token)
})
.collect::<Vec<String>>()
.join(", ");
// Upsert to accomplish multiple updates at once.
// tl;dr https://stackoverflow.com/a/34866431
// ALSO THIS IS NOT SANITIZED.
let query_inner_positions = rule_token_to_order_map.iter()
.map(|(token, position)| {
format!("when token = '{}' then '{}'", token.as_str(), position)
})
.collect::<Vec<String>>()
.join("\n");
let query_inner_ip_addresses = rule_token_to_order_map.iter()
.map(|(token, position)| {
format!("when token = '{}' then '{}'", token.as_str(), ip_address_update)
})
.collect::<Vec<String>>()
.join("\n");
let query = format!(r#"
INSERT INTO twitch_event_rules (token, user_specified_rule_order, ip_address_update)
VALUES
{}
ON DUPLICATE KEY UPDATE
token=VALUES(token),
user_specified_rule_order=VALUES(user_specified_rule_order),
ip_address_update=VALUES(ip_address_update)
WHERE
user_token = {}
"#, query_inner, user_token);
UPDATE twitch_event_rules
SET
user_specified_rule_order = (case
{}
end),
ip_address_last_update = (case
{}
end)
WHERE user_token = '{}'
AND deleted_at IS NULL
AND token IN ({})
"#, query_inner_positions, query_inner_ip_addresses, user_token, rule_tokens);
// NB: This, unfortunately, cannot be statically checked.
let mut query = sqlx::query(&query);