use std::fmt;
use crate::common::*;
mod catalog;
mod column;
mod data_type;
mod table;
pub(crate) use self::column::PgColumn;
pub(crate) use self::data_type::{PgDataType, PgScalarDataType};
pub(crate) use self::table::PgCreateTable;
pub(crate) fn pg_quote(s: &str) -> String {
format!("'{}'", s.replace('\'', "''"))
}
#[test]
fn pg_quote_doubles_single_quotes() {
let examples = &[
("", "''"),
("a", "'a'"),
("'", "''''"),
("'hello'", "'''hello'''"),
];
for &(input, expected) in examples {
assert_eq!(pg_quote(input), expected);
}
}
pub(crate) struct Ident<'a>(pub(crate) &'a str);
impl<'a> fmt::Display for Ident<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\"")?;
write!(f, "{}", self.0.replace('"', "\"\""))?;
write!(f, "\"")?;
Ok(())
}
}
pub(crate) struct TableName<'a>(pub(crate) &'a str);
impl<'a> TableName<'a> {
pub(crate) fn split(&self) -> Result<(Option<&str>, &str)> {
let components = self.0.splitn(2, '.').collect::<Vec<_>>();
match components.len() {
1 => Ok((None, components[0])),
2 => Ok((Some(components[0]), components[1])),
_ => Err(format_err!("cannot parse table name {:?}", self.0)),
}
}
}
impl<'a> fmt::Display for TableName<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let components = self.split().map_err(|err| {
eprintln!("{}", err);
fmt::Error
})?;
match components {
(Some(namespace), table) => {
write!(f, "{}.{}", Ident(namespace), Ident(table))?
}
(None, table) => write!(f, "{}", Ident(table))?,
}
Ok(())
}
}
#[test]
fn table_name_is_quoted_correctly() {
let formatted = format!("{}", TableName("testme1.lat-\"lon"));
assert_eq!(formatted, "\"testme1\".\"lat-\"\"lon\"");
}