pub(crate) fn literal(conn: &crate::Connection, str: &str) -> std::result::Result<String, String> {
let c_str = crate::ffi::to_cstr(str);
unsafe {
let raw = pq_sys::PQescapeLiteral(conn.into(), c_str.as_ptr(), str.len() as pq_sys::size_t);
if raw.is_null() {
return Err(conn
.error_message()
.unwrap_or_else(|| "Unknow error".to_string()));
}
let escaped = crate::ffi::to_string(raw);
pq_sys::PQfreemem(raw as *mut std::ffi::c_void);
Ok(escaped)
}
}
pub fn identifier(conn: &crate::Connection, str: &str) -> std::result::Result<String, String> {
let c_str = crate::ffi::to_cstr(str);
unsafe {
let raw =
pq_sys::PQescapeIdentifier(conn.into(), c_str.as_ptr(), str.len() as pq_sys::size_t);
if raw.is_null() {
return Err(conn
.error_message()
.unwrap_or_else(|| "Unknow error".to_string()));
}
let escaped = crate::ffi::to_string(raw);
pq_sys::PQfreemem(raw as *mut std::ffi::c_void);
Ok(escaped)
}
}
pub(crate) fn string_conn(
conn: &crate::Connection,
from: &str,
) -> std::result::Result<String, String> {
let mut error = 0;
let cstring = crate::ffi::new_cstring(2 * from.len() + 1);
let raw = cstring.into_raw();
let c_from = crate::ffi::to_cstr(from);
unsafe {
pq_sys::PQescapeStringConn(
conn.into(),
raw,
c_from.as_ptr(),
from.len() as pq_sys::size_t,
&mut error,
);
if error != 0 {
return Err(conn
.error_message()
.unwrap_or_else(|| "Unknow error".to_string()));
}
};
let to = crate::ffi::from_raw(raw);
Ok(to)
}
#[deprecated(note = "Use libpq::Connection::escape_string instead")]
pub fn string(from: &str) -> String {
let c_from = crate::ffi::to_cstr(from);
let cstring = crate::ffi::new_cstring(2 * from.len() + 1);
let raw = cstring.into_raw();
unsafe {
pq_sys::PQescapeString(raw, c_from.as_ptr(), from.len() as pq_sys::size_t);
};
crate::ffi::from_raw(raw)
}
pub(crate) fn bytea_conn(
conn: &crate::Connection,
from: &[u8],
) -> std::result::Result<Vec<u8>, String> {
let to = unsafe {
let mut len = 0;
let tmp = pq_sys::PQescapeByteaConn(
conn.into(),
from.as_ptr(),
from.len() as pq_sys::size_t,
&mut len,
);
if tmp.is_null() {
return Err(conn
.error_message()
.unwrap_or_else(|| "Unknow error".to_string()));
}
let to = std::slice::from_raw_parts(tmp, len as usize - 1).to_vec();
pq_sys::PQfreemem(tmp as *mut std::ffi::c_void);
to
};
Ok(to)
}
#[deprecated(note = "Use libpq::Connection::escape_bytea instead")]
pub fn bytea(from: &[u8]) -> std::result::Result<Vec<u8>, String> {
let to = unsafe {
let mut len = 0;
let tmp = pq_sys::PQescapeBytea(from.as_ptr(), from.len() as pq_sys::size_t, &mut len);
let to = std::slice::from_raw_parts(tmp, len as usize - 1).to_vec();
pq_sys::PQfreemem(tmp as *mut std::ffi::c_void);
to
};
Ok(to)
}
pub fn unescape_bytea(from: &[u8]) -> std::result::Result<Vec<u8>, ()> {
let to = unsafe {
let mut len = 0;
let tmp = pq_sys::PQunescapeBytea(from.as_ptr(), &mut len);
if tmp.is_null() {
return Err(());
}
let to = std::slice::from_raw_parts(tmp, len as usize).to_vec();
pq_sys::PQfreemem(tmp as *mut std::ffi::c_void);
to
};
Ok(to)
}
#[cfg(test)]
mod test {
#[test]
fn literal() {
let conn = crate::test::new_conn();
assert_eq!(
crate::escape::literal(&conn, "foo"),
Ok("'foo'".to_string())
);
}
#[test]
fn identifier() {
let conn = crate::test::new_conn();
assert_eq!(
crate::escape::identifier(&conn, "foo"),
Ok("\"foo\"".to_string())
);
}
#[test]
fn string_conn() {
let conn = crate::test::new_conn();
assert_eq!(
crate::escape::string_conn(&conn, "'foo'"),
Ok("''foo''".to_string())
);
}
#[test]
fn string() {
#![allow(deprecated)]
assert_eq!(crate::escape::string("'foo'"), "''foo''".to_string());
}
#[test]
fn bytea_conn() {
let conn = crate::test::new_conn();
assert_eq!(
crate::escape::bytea_conn(&conn, b"\0"),
Ok(b"\\x00".to_vec())
);
}
#[test]
fn bytea() {
#![allow(deprecated)]
assert_eq!(crate::escape::bytea(b"'foo'"), Ok(b"''foo''".to_vec()));
}
#[test]
fn unescape_bytea() {
#![allow(deprecated)]
assert_eq!(crate::escape::bytea(b"'foo'"), Ok(b"''foo''".to_vec()));
}
}