Death to ~str!

This commit is contained in:
Steven Fackler 2014-05-15 19:59:01 -07:00
parent dcd47041d0
commit 7849a5843d
4 changed files with 44 additions and 52 deletions

View File

@ -220,7 +220,7 @@ types. The driver currently supports the following conversions:
<td>DOUBLE PRECISION</td> <td>DOUBLE PRECISION</td>
</tr> </tr>
<tr> <tr>
<td>str</td> <td>str/StrBuf</td>
<td>VARCHAR, CHAR(n), TEXT</td> <td>VARCHAR, CHAR(n), TEXT</td>
</tr> </tr>
<tr> <tr>

View File

@ -567,18 +567,18 @@ impl InnerPostgresConnection {
fn prepare<'a>(&mut self, query: &str, conn: &'a PostgresConnection) fn prepare<'a>(&mut self, query: &str, conn: &'a PostgresConnection)
-> PostgresResult<PostgresStatement<'a>> { -> PostgresResult<PostgresStatement<'a>> {
let stmt_name = format!("s{}", self.next_stmt_id); let stmt_name = format!("s{}", self.next_stmt_id).into_strbuf();
self.next_stmt_id += 1; self.next_stmt_id += 1;
try_pg!(self.write_messages([ try_pg!(self.write_messages([
Parse { Parse {
name: stmt_name, name: stmt_name.as_slice(),
query: query, query: query,
param_types: [] param_types: []
}, },
Describe { Describe {
variant: 'S' as u8, variant: 'S' as u8,
name: stmt_name name: stmt_name.as_slice(),
}, },
Sync])); Sync]));
@ -1031,7 +1031,7 @@ impl<'conn> PostgresTransaction<'conn> {
/// A prepared statement /// A prepared statement
pub struct PostgresStatement<'conn> { pub struct PostgresStatement<'conn> {
conn: &'conn PostgresConnection, conn: &'conn PostgresConnection,
name: ~str, name: StrBuf,
param_types: Vec<PostgresType>, param_types: Vec<PostgresType>,
result_desc: Vec<ResultDescription>, result_desc: Vec<ResultDescription>,
next_portal_id: Cell<uint>, next_portal_id: Cell<uint>,
@ -1117,9 +1117,9 @@ impl<'conn> PostgresStatement<'conn> {
-> PostgresResult<PostgresRows<'a>> { -> PostgresResult<PostgresRows<'a>> {
let id = self.next_portal_id.get(); let id = self.next_portal_id.get();
self.next_portal_id.set(id + 1); self.next_portal_id.set(id + 1);
let portal_name = format!("{}p{}", self.name, id); let portal_name = format!("{}p{}", self.name, id).into_strbuf();
try!(self.inner_execute(portal_name, row_limit, params)); try!(self.inner_execute(portal_name.as_slice(), row_limit, params));
let mut result = PostgresRows { let mut result = PostgresRows {
stmt: self, stmt: self,
@ -1238,7 +1238,7 @@ pub struct ResultDescription {
/// An iterator over the resulting rows of a query. /// An iterator over the resulting rows of a query.
pub struct PostgresRows<'stmt> { pub struct PostgresRows<'stmt> {
stmt: &'stmt PostgresStatement<'stmt>, stmt: &'stmt PostgresStatement<'stmt>,
name: ~str, name: StrBuf,
data: RingBuf<Vec<Option<Vec<u8>>>>, data: RingBuf<Vec<Option<Vec<u8>>>>,
row_limit: uint, row_limit: uint,
more_rows: bool, more_rows: bool,
@ -1298,7 +1298,7 @@ impl<'stmt> PostgresRows<'stmt> {
fn execute(&mut self) -> PostgresResult<()> { fn execute(&mut self) -> PostgresResult<()> {
try_pg!(self.stmt.conn.write_messages([ try_pg!(self.stmt.conn.write_messages([
Execute { Execute {
portal: self.name, portal: self.name.as_slice(),
max_rows: self.row_limit as i32 max_rows: self.row_limit as i32
}, },
Sync])); Sync]));

View File

@ -408,8 +408,8 @@ fn test_i8_params() {
#[test] #[test]
fn test_name_params() { fn test_name_params() {
test_type("NAME", [(Some("hello world".to_owned()), "'hello world'"), test_type("NAME", [(Some("hello world".to_strbuf()), "'hello world'"),
(Some("イロハニホヘト チリヌルヲ".to_owned()), "'イロハニホヘト チリヌルヲ'"), (Some("イロハニホヘト チリヌルヲ".to_strbuf()), "'イロハニホヘト チリヌルヲ'"),
(None, "NULL")]); (None, "NULL")]);
} }
@ -449,15 +449,15 @@ fn test_f64_params() {
#[test] #[test]
fn test_varchar_params() { fn test_varchar_params() {
test_type("VARCHAR", [(Some("hello world".to_owned()), "'hello world'"), test_type("VARCHAR", [(Some("hello world".to_strbuf()), "'hello world'"),
(Some("イロハニホヘト チリヌルヲ".to_owned()), "'イロハニホヘト チリヌルヲ'"), (Some("イロハニホヘト チリヌルヲ".to_strbuf()), "'イロハニホヘト チリヌルヲ'"),
(None, "NULL")]); (None, "NULL")]);
} }
#[test] #[test]
fn test_text_params() { fn test_text_params() {
test_type("TEXT", [(Some("hello world".to_owned()), "'hello world'"), test_type("TEXT", [(Some("hello world".to_strbuf()), "'hello world'"),
(Some("イロハニホヘト チリヌルヲ".to_owned()), "'イロハニホヘト チリヌルヲ'"), (Some("イロハニホヘト チリヌルヲ".to_strbuf()), "'イロハニホヘト チリヌルヲ'"),
(None, "NULL")]); (None, "NULL")]);
} }
@ -474,7 +474,7 @@ fn test_bpchar_params() {
let stmt = or_fail!(conn.prepare("SELECT b FROM foo ORDER BY id")); let stmt = or_fail!(conn.prepare("SELECT b FROM foo ORDER BY id"));
let res = or_fail!(stmt.query([])); let res = or_fail!(stmt.query([]));
assert_eq!(vec!(Some("12345".to_owned()), Some("123 ".to_owned()), None), assert_eq!(vec!(Some("12345".to_strbuf()), Some("123 ".to_strbuf()), None),
res.map(|row| row[1]).collect()); res.map(|row| row[1]).collect());
} }
@ -570,13 +570,14 @@ fn test_tstzrange_params() {
macro_rules! test_array_params( macro_rules! test_array_params(
($name:expr, $v1:expr, $s1:expr, $v2:expr, $s2:expr, $v3:expr, $s3:expr) => ({ ($name:expr, $v1:expr, $s1:expr, $v2:expr, $s2:expr, $v3:expr, $s3:expr) => ({
let tests = [(Some(ArrayBase::from_vec(vec!(Some($v1), Some($v2), None), 1)), let tests = [(Some(ArrayBase::from_vec(vec!(Some($v1), Some($v2), None), 1)),
"'{" + $s1 + "," + $s2 + ",NULL}'"), format!(r"'\{{},{},NULL\}'", $s1, $s2).into_strbuf()),
(None, "NULL".to_owned())]; (None, "NULL".to_strbuf())];
test_type($name + "[]", tests); test_type($name + "[]", tests);
let mut a = ArrayBase::from_vec(vec!(Some($v1), Some($v2)), 0); let mut a = ArrayBase::from_vec(vec!(Some($v1), Some($v2)), 0);
a.wrap(-1); a.wrap(-1);
a.push_move(ArrayBase::from_vec(vec!(None, Some($v3)), 0)); a.push_move(ArrayBase::from_vec(vec!(None, Some($v3)), 0));
let tests = [(Some(a), "'[-1:0][0:1]={{" + $s1 + "," + $s2 + "},{NULL," + $s3 + "}}'")]; let tests = [(Some(a), format!(r"'[-1:0][0:1]=\{\{{},{}\},\{NULL,{}\}\}'",
$s1, $s2, $s3).into_strbuf())];
test_type($name + "[][]", tests); test_type($name + "[][]", tests);
}) })
) )
@ -600,8 +601,8 @@ fn test_chararray_params() {
#[test] #[test]
fn test_namearray_params() { fn test_namearray_params() {
test_array_params!("NAME", "hello".to_owned(), "hello", "world".to_owned(), test_array_params!("NAME", "hello".to_strbuf(), "hello", "world".to_strbuf(),
"world", "!".to_owned(), "!"); "world", "!".to_strbuf(), "!");
} }
#[test] #[test]
@ -616,20 +617,20 @@ fn test_int4array_params() {
#[test] #[test]
fn test_textarray_params() { fn test_textarray_params() {
test_array_params!("TEXT", "hello".to_owned(), "hello", "world".to_owned(), test_array_params!("TEXT", "hello".to_strbuf(), "hello", "world".to_strbuf(),
"world", "!".to_owned(), "!"); "world", "!".to_strbuf(), "!");
} }
#[test] #[test]
fn test_charnarray_params() { fn test_charnarray_params() {
test_array_params!("CHAR(5)", "hello".to_owned(), "hello", test_array_params!("CHAR(5)", "hello".to_strbuf(), "hello",
"world".to_owned(), "world", "! ".to_owned(), "!"); "world".to_strbuf(), "world", "! ".to_strbuf(), "!");
} }
#[test] #[test]
fn test_varchararray_params() { fn test_varchararray_params() {
test_array_params!("VARCHAR", "hello".to_owned(), "hello", test_array_params!("VARCHAR", "hello".to_strbuf(), "hello",
"world".to_owned(), "world", "!".to_owned(), "!"); "world".to_strbuf(), "world", "!".to_strbuf(), "!");
} }
#[test] #[test]
@ -713,10 +714,10 @@ fn test_hstore_params() {
}) })
) )
test_type("hstore", test_type("hstore",
[(Some(make_map!("a".to_owned() => Some("1".to_owned()))), "'a=>1'"), [(Some(make_map!("a".to_strbuf() => Some("1".to_strbuf()))), "'a=>1'"),
(Some(make_map!("hello".to_owned() => Some("world!".to_owned()), (Some(make_map!("hello".to_strbuf() => Some("world!".to_strbuf()),
"hola".to_owned() => Some("mundo!".to_owned()), "hola".to_strbuf() => Some("mundo!".to_strbuf()),
"what".to_owned() => None)), "what".to_strbuf() => None)),
"'hello=>world!,hola=>mundo!,what=>NULL'"), "'hello=>world!,hola=>mundo!,what=>NULL'"),
(None, "NULL")]); (None, "NULL")]);
} }

View File

@ -268,13 +268,6 @@ impl RawFromSql for Vec<u8> {
} }
} }
impl RawFromSql for ~str {
fn raw_from_sql<R: Reader>(raw: &mut R) -> PostgresResult<~str> {
let s: PostgresResult<StrBuf> = RawFromSql::raw_from_sql(raw);
s.map(|s| s.into_owned())
}
}
impl RawFromSql for StrBuf { impl RawFromSql for StrBuf {
fn raw_from_sql<R: Reader>(raw: &mut R) -> PostgresResult<StrBuf> { fn raw_from_sql<R: Reader>(raw: &mut R) -> PostgresResult<StrBuf> {
Ok(StrBuf::from_utf8(try_pg!(raw.read_to_end())).unwrap()) Ok(StrBuf::from_utf8(try_pg!(raw.read_to_end())).unwrap())
@ -406,7 +399,6 @@ macro_rules! from_raw_from_impl(
from_raw_from_impl!(PgBool, bool) from_raw_from_impl!(PgBool, bool)
from_raw_from_impl!(PgByteA, Vec<u8>) from_raw_from_impl!(PgByteA, Vec<u8>)
from_raw_from_impl!(PgVarchar | PgText | PgCharN | PgName, ~str)
from_raw_from_impl!(PgVarchar | PgText | PgCharN | PgName, StrBuf) from_raw_from_impl!(PgVarchar | PgText | PgCharN | PgName, StrBuf)
from_raw_from_impl!(PgChar, i8) from_raw_from_impl!(PgChar, i8)
from_raw_from_impl!(PgInt2, i16) from_raw_from_impl!(PgInt2, i16)
@ -462,7 +454,6 @@ from_array_impl!(PgByteAArray, Vec<u8>)
from_array_impl!(PgCharArray, i8) from_array_impl!(PgCharArray, i8)
from_array_impl!(PgInt2Array, i16) from_array_impl!(PgInt2Array, i16)
from_array_impl!(PgInt4Array, i32) from_array_impl!(PgInt4Array, i32)
from_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray | PgNameArray, ~str)
from_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray | PgNameArray, StrBuf) from_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray | PgNameArray, StrBuf)
from_array_impl!(PgInt8Array, i64) from_array_impl!(PgInt8Array, i64)
from_array_impl!(PgTimestampArray | PgTimestampTZArray, Timespec) from_array_impl!(PgTimestampArray | PgTimestampTZArray, Timespec)
@ -474,9 +465,9 @@ from_array_impl!(PgInt4RangeArray, Range<i32>)
from_array_impl!(PgTsRangeArray | PgTstzRangeArray, Range<Timespec>) from_array_impl!(PgTsRangeArray | PgTstzRangeArray, Range<Timespec>)
from_array_impl!(PgInt8RangeArray, Range<i64>) from_array_impl!(PgInt8RangeArray, Range<i64>)
impl FromSql for Option<HashMap<~str, Option<~str>>> { impl FromSql for Option<HashMap<StrBuf, Option<StrBuf>>> {
fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>) fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>)
-> PostgresResult<Option<HashMap<~str, Option<~str>>>> { -> PostgresResult<Option<HashMap<StrBuf, Option<StrBuf>>>> {
match *ty { match *ty {
PgUnknownType { name: ref name, .. } PgUnknownType { name: ref name, .. }
if "hstore" == name.as_slice() => {} if "hstore" == name.as_slice() => {}
@ -493,14 +484,14 @@ impl FromSql for Option<HashMap<~str, Option<~str>>> {
for _ in range(0, count) { for _ in range(0, count) {
let key_len = try_pg!(rdr.read_be_i32()); let key_len = try_pg!(rdr.read_be_i32());
let key = try_pg!(rdr.read_exact(key_len as uint)); let key = try_pg!(rdr.read_exact(key_len as uint));
let key = StrBuf::from_utf8(key).unwrap().into_owned(); let key = StrBuf::from_utf8(key).unwrap();
let val_len = try_pg!(rdr.read_be_i32()); let val_len = try_pg!(rdr.read_be_i32());
let val = if val_len < 0 { let val = if val_len < 0 {
None None
} else { } else {
let val = try_pg!(rdr.read_exact(val_len as uint)); let val = try_pg!(rdr.read_exact(val_len as uint));
Some(StrBuf::from_utf8(val).unwrap().into_owned()) Some(StrBuf::from_utf8(val).unwrap())
}; };
map.insert(key, val); map.insert(key, val);
@ -512,11 +503,11 @@ impl FromSql for Option<HashMap<~str, Option<~str>>> {
} }
} }
impl FromSql for HashMap<~str, Option<~str>> { impl FromSql for HashMap<StrBuf, Option<StrBuf>> {
fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>) fn from_sql(ty: &PostgresType, raw: &Option<Vec<u8>>)
-> PostgresResult<HashMap<~str, Option<~str>>> { -> PostgresResult<HashMap<StrBuf, Option<StrBuf>>> {
// FIXME when you can specify Self types properly // FIXME when you can specify Self types properly
let ret: PostgresResult<Option<HashMap<~str, Option<~str>>>> = let ret: PostgresResult<Option<HashMap<StrBuf, Option<StrBuf>>>> =
FromSql::from_sql(ty, raw); FromSql::from_sql(ty, raw);
match ret { match ret {
Ok(Some(val)) => Ok(val), Ok(Some(val)) => Ok(val),
@ -561,7 +552,7 @@ impl RawToSql for Vec<u8> {
} }
} }
impl RawToSql for ~str { impl RawToSql for StrBuf {
fn raw_to_sql<W: Writer>(&self, w: &mut W) -> PostgresResult<()> { fn raw_to_sql<W: Writer>(&self, w: &mut W) -> PostgresResult<()> {
Ok(try_pg!(w.write(self.as_bytes()))) Ok(try_pg!(w.write(self.as_bytes())))
} }
@ -701,7 +692,7 @@ macro_rules! to_raw_to_impl(
to_raw_to_impl!(PgBool, bool) to_raw_to_impl!(PgBool, bool)
to_raw_to_impl!(PgByteA, Vec<u8>) to_raw_to_impl!(PgByteA, Vec<u8>)
to_raw_to_impl!(PgVarchar | PgText | PgCharN | PgName, ~str) to_raw_to_impl!(PgVarchar | PgText | PgCharN | PgName, StrBuf)
to_raw_to_impl!(PgJson, Json) to_raw_to_impl!(PgJson, Json)
to_raw_to_impl!(PgChar, i8) to_raw_to_impl!(PgChar, i8)
to_raw_to_impl!(PgInt2, i16) to_raw_to_impl!(PgInt2, i16)
@ -779,8 +770,8 @@ to_array_impl!(PgByteAArray, Vec<u8>)
to_array_impl!(PgCharArray, i8) to_array_impl!(PgCharArray, i8)
to_array_impl!(PgInt2Array, i16) to_array_impl!(PgInt2Array, i16)
to_array_impl!(PgInt4Array, i32) to_array_impl!(PgInt4Array, i32)
to_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray | PgNameArray, ~str)
to_array_impl!(PgInt8Array, i64) to_array_impl!(PgInt8Array, i64)
to_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray | PgNameArray, StrBuf)
to_array_impl!(PgTimestampArray | PgTimestampTZArray, Timespec) to_array_impl!(PgTimestampArray | PgTimestampTZArray, Timespec)
to_array_impl!(PgFloat4Array, f32) to_array_impl!(PgFloat4Array, f32)
to_array_impl!(PgFloat8Array, f64) to_array_impl!(PgFloat8Array, f64)
@ -790,7 +781,7 @@ to_array_impl!(PgTsRangeArray | PgTstzRangeArray, Range<Timespec>)
to_array_impl!(PgInt8RangeArray, Range<i64>) to_array_impl!(PgInt8RangeArray, Range<i64>)
to_array_impl!(PgJsonArray, Json) to_array_impl!(PgJsonArray, Json)
impl ToSql for HashMap<~str, Option<~str>> { impl ToSql for HashMap<StrBuf, Option<StrBuf>> {
fn to_sql(&self, ty: &PostgresType) fn to_sql(&self, ty: &PostgresType)
-> PostgresResult<(Format, Option<Vec<u8>>)> { -> PostgresResult<(Format, Option<Vec<u8>>)> {
match *ty { match *ty {
@ -820,7 +811,7 @@ impl ToSql for HashMap<~str, Option<~str>> {
} }
} }
impl ToSql for Option<HashMap<~str, Option<~str>>> { impl ToSql for Option<HashMap<StrBuf, Option<StrBuf>>> {
fn to_sql(&self, ty: &PostgresType) fn to_sql(&self, ty: &PostgresType)
-> PostgresResult<(Format, Option<Vec<u8>>)> { -> PostgresResult<(Format, Option<Vec<u8>>)> {
match *ty { match *ty {