pub fn convert_mysql_placeholders_to_postgresql(sql: &str) -> String {
let mut result = String::with_capacity(sql.len() + 32); let mut chars = sql.chars().peekable();
let mut placeholder_count = 0;
let mut in_single_quote = false;
let mut in_double_quote = false;
let mut in_line_comment = false;
let mut in_block_comment = false;
while let Some(ch) = chars.next() {
match ch {
'\'' if !in_double_quote && !in_line_comment && !in_block_comment => {
in_single_quote = !in_single_quote;
result.push(ch);
}
'"' if !in_single_quote && !in_line_comment && !in_block_comment => {
in_double_quote = !in_double_quote;
result.push(ch);
}
'-' if !in_single_quote && !in_double_quote && !in_block_comment => {
if chars.peek() == Some(&'-') {
chars.next(); in_line_comment = true;
result.push_str("--");
} else {
result.push(ch);
}
}
'/' if !in_single_quote && !in_double_quote && !in_line_comment => {
if chars.peek() == Some(&'*') {
chars.next(); in_block_comment = true;
result.push_str("/*");
} else {
result.push(ch);
}
}
'*' if in_block_comment => {
if chars.peek() == Some(&'/') {
chars.next(); in_block_comment = false;
result.push_str("*/");
} else {
result.push(ch);
}
}
'\n' | '\r' if in_line_comment => {
in_line_comment = false;
result.push(ch);
}
'\\' if (in_single_quote || in_double_quote)
&& !in_line_comment
&& !in_block_comment =>
{
result.push(ch);
if let Some(next_ch) = chars.next() {
result.push(next_ch); }
}
'\\' if !in_single_quote
&& !in_double_quote
&& !in_line_comment
&& !in_block_comment =>
{
if chars.peek() == Some(&'?') {
chars.next(); result.push('?'); } else {
result.push(ch);
}
}
'?' if !in_single_quote
&& !in_double_quote
&& !in_line_comment
&& !in_block_comment =>
{
if chars.peek() == Some(&'?') {
chars.next(); result.push('?'); } else {
placeholder_count += 1;
result.push('$');
result.push_str(&placeholder_count.to_string());
}
}
_ => {
result.push(ch);
}
}
}
result
}