parent
b2adca1851
commit
ac9f77a62a
5 changed files with 44 additions and 14 deletions
lib/src/sql
|
@ -1,7 +1,7 @@
|
|||
use crate::sql::common::{take_digits, take_digits_range, take_u32_len};
|
||||
use crate::sql::duration::Duration;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_str;
|
||||
use crate::sql::escape::quote_str;
|
||||
use crate::sql::strand::Strand;
|
||||
use chrono::{DateTime, FixedOffset, Offset, SecondsFormat, TimeZone, Utc};
|
||||
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
|
||||
|
@ -89,7 +89,7 @@ impl Datetime {
|
|||
|
||||
impl Display for Datetime {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
Display::fmt(&escape_str(&self.0.to_rfc3339_opts(SecondsFormat::AutoSi, true)), f)
|
||||
Display::fmt("e_str(&self.0.to_rfc3339_opts(SecondsFormat::AutoSi, true)), f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,13 +14,43 @@ const DOUBLE_ESC: &str = r#"\""#;
|
|||
const BACKTICK: char = '`';
|
||||
const BACKTICK_ESC: &str = r#"\`"#;
|
||||
|
||||
/// Quotes a string with single or double quotes:
|
||||
/// - cat -> 'cat'
|
||||
/// - cat's -> "cat's"
|
||||
/// - cat's "toy" -> "cat's \"toy\""
|
||||
///
|
||||
/// Escapes / as //
|
||||
#[inline]
|
||||
pub fn escape_str(s: &str) -> Cow<'_, str> {
|
||||
if s.contains(SINGLE) {
|
||||
escape_normal(s, DOUBLE, DOUBLE, DOUBLE_ESC)
|
||||
} else {
|
||||
Cow::Owned(format!("{SINGLE}{s}{SINGLE}"))
|
||||
pub fn quote_str(s: &str) -> String {
|
||||
// Rough approximation of capacity, which may be exceeded
|
||||
// if things must be escaped.
|
||||
let mut ret = String::with_capacity(2 + s.len());
|
||||
|
||||
fn escape_into(into: &mut String, s: &str, escape_double: bool) {
|
||||
// Based on internals of str::replace
|
||||
let mut last_end = 0;
|
||||
for (start, part) in s.match_indices(|c| c == '\\' || (c == DOUBLE && escape_double)) {
|
||||
into.push_str(&s[last_end..start]);
|
||||
into.push_str(if part == "\\" {
|
||||
"\\\\"
|
||||
} else {
|
||||
DOUBLE_ESC
|
||||
});
|
||||
last_end = start + part.len();
|
||||
}
|
||||
into.push_str(&s[last_end..s.len()]);
|
||||
}
|
||||
|
||||
let quote = if s.contains(SINGLE) {
|
||||
DOUBLE
|
||||
} else {
|
||||
SINGLE
|
||||
};
|
||||
|
||||
ret.push(quote);
|
||||
escape_into(&mut ret, s, quote == DOUBLE);
|
||||
ret.push(quote);
|
||||
ret
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::sql::comment::{mightbespace, shouldbespace};
|
|||
use crate::sql::common::commas;
|
||||
use crate::sql::duration::{duration, Duration};
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_str;
|
||||
use crate::sql::escape::quote_str;
|
||||
use crate::sql::filter::{filters, Filter};
|
||||
use crate::sql::fmt::is_pretty;
|
||||
use crate::sql::fmt::pretty_indent;
|
||||
|
@ -452,7 +452,7 @@ impl DefineLoginStatement {
|
|||
|
||||
impl Display for DefineLoginStatement {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "DEFINE LOGIN {} ON {} PASSHASH {}", self.name, self.base, escape_str(&self.hash))
|
||||
write!(f, "DEFINE LOGIN {} ON {} PASSHASH {}", self.name, self.base, quote_str(&self.hash))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -601,7 +601,7 @@ impl Display for DefineTokenStatement {
|
|||
self.name,
|
||||
self.base,
|
||||
self.kind,
|
||||
escape_str(&self.code)
|
||||
quote_str(&self.code)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::sql::error::Error::Parser;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_str;
|
||||
use crate::sql::escape::quote_str;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{escaped_transform, is_not, tag, take, take_while_m_n};
|
||||
use nom::character::complete::char;
|
||||
|
@ -73,7 +73,7 @@ impl Strand {
|
|||
|
||||
impl Display for Strand {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
Display::fmt(&escape_str(&self.0), f)
|
||||
Display::fmt("e_str(&self.0), f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::sql::common::is_hex;
|
||||
use crate::sql::error::IResult;
|
||||
use crate::sql::escape::escape_str;
|
||||
use crate::sql::escape::quote_str;
|
||||
use crate::sql::strand::Strand;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::take_while_m_n;
|
||||
|
@ -99,7 +99,7 @@ impl Uuid {
|
|||
|
||||
impl Display for Uuid {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
Display::fmt(&escape_str(&self.0.to_string()), f)
|
||||
Display::fmt("e_str(&self.0.to_string()), f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue