2022-09-27 21:35:30 +00:00
|
|
|
use crate::sql::common::val_u8;
|
2022-10-16 23:04:07 +00:00
|
|
|
use nom::character::is_digit;
|
2022-09-27 21:35:30 +00:00
|
|
|
use std::borrow::Cow;
|
2022-05-15 08:34:29 +00:00
|
|
|
|
2022-10-19 10:09:09 +00:00
|
|
|
const SINGLE: char = '\'';
|
|
|
|
|
2022-10-16 23:04:07 +00:00
|
|
|
const BRACKETL: char = '⟨';
|
|
|
|
const BRACKETR: char = '⟩';
|
|
|
|
const BRACKET_ESC: &str = r#"\⟩"#;
|
2022-07-06 09:08:11 +00:00
|
|
|
|
2022-05-15 08:34:29 +00:00
|
|
|
const DOUBLE: char = '"';
|
|
|
|
const DOUBLE_ESC: &str = r#"\""#;
|
|
|
|
|
|
|
|
const BACKTICK: char = '`';
|
|
|
|
const BACKTICK_ESC: &str = r#"\`"#;
|
|
|
|
|
|
|
|
#[inline]
|
2022-11-27 11:43:16 +00:00
|
|
|
pub fn escape_str(s: &str) -> Cow<'_, str> {
|
2022-10-19 10:09:09 +00:00
|
|
|
if s.contains(SINGLE) {
|
2022-11-27 11:43:16 +00:00
|
|
|
escape_normal(s, DOUBLE, DOUBLE, DOUBLE_ESC)
|
2022-10-19 10:09:09 +00:00
|
|
|
} else {
|
2022-11-27 11:43:16 +00:00
|
|
|
Cow::Owned(format!("{}{}{}", SINGLE, s, SINGLE))
|
2022-10-19 10:09:09 +00:00
|
|
|
}
|
2022-05-15 08:34:29 +00:00
|
|
|
}
|
|
|
|
|
2022-07-06 09:08:11 +00:00
|
|
|
#[inline]
|
2022-10-16 23:04:07 +00:00
|
|
|
/// Escapes a key if necessary
|
|
|
|
pub fn escape_key(s: &str) -> Cow<'_, str> {
|
|
|
|
escape_normal(s, DOUBLE, DOUBLE, DOUBLE_ESC)
|
2022-07-06 09:08:11 +00:00
|
|
|
}
|
|
|
|
|
2022-05-15 08:34:29 +00:00
|
|
|
#[inline]
|
2022-10-16 23:04:07 +00:00
|
|
|
/// Escapes an id if necessary
|
|
|
|
pub fn escape_rid(s: &str) -> Cow<'_, str> {
|
|
|
|
escape_numeric(s, BRACKETL, BRACKETR, BRACKET_ESC)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
/// Escapes an ident if necessary
|
|
|
|
pub fn escape_ident(s: &str) -> Cow<'_, str> {
|
|
|
|
escape_numeric(s, BACKTICK, BACKTICK, BACKTICK_ESC)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn escape_normal<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
|
|
|
|
// Loop over each character
|
2022-09-27 21:35:30 +00:00
|
|
|
for x in s.bytes() {
|
2022-10-16 23:04:07 +00:00
|
|
|
// Check if character is allowed
|
2022-09-27 21:35:30 +00:00
|
|
|
if !val_u8(x) {
|
2022-10-16 23:04:07 +00:00
|
|
|
return Cow::Owned(format!("{}{}{}", l, s.replace(r, e), r));
|
2022-05-15 08:34:29 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-16 23:04:07 +00:00
|
|
|
// Output the value
|
2022-09-27 21:35:30 +00:00
|
|
|
Cow::Borrowed(s)
|
2022-05-15 08:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2022-10-16 23:04:07 +00:00
|
|
|
pub fn escape_numeric<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
|
|
|
|
// Presume this is numeric
|
|
|
|
let mut numeric = true;
|
|
|
|
// Loop over each character
|
2022-09-27 21:35:30 +00:00
|
|
|
for x in s.bytes() {
|
2022-10-16 23:04:07 +00:00
|
|
|
// Check if character is allowed
|
2022-09-27 21:35:30 +00:00
|
|
|
if !val_u8(x) {
|
2022-10-16 23:04:07 +00:00
|
|
|
return Cow::Owned(format!("{}{}{}", l, s.replace(r, e), r));
|
|
|
|
}
|
|
|
|
// Check if character is non-numeric
|
|
|
|
if !is_digit(x) {
|
|
|
|
numeric = false;
|
2022-05-15 08:34:29 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-16 23:04:07 +00:00
|
|
|
// Output the id value
|
|
|
|
match numeric {
|
|
|
|
// This is numeric so escape it
|
|
|
|
true => Cow::Owned(format!("{}{}{}", l, s.replace(r, e), r)),
|
|
|
|
// No need to escape the value
|
|
|
|
_ => Cow::Borrowed(s),
|
|
|
|
}
|
2022-05-15 08:34:29 +00:00
|
|
|
}
|