Skip to content

Commit 95fbb4f

Browse files
committed
Support BYTEA[]
1 parent 08c217e commit 95fbb4f

3 files changed

Lines changed: 52 additions & 25 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ types. The driver currently supports the following conversions:
262262
<td>types::array::ArrayBase&lt;Option&lt;bool&gt;&gt;</td>
263263
<td>BOOL[], BOOL[][], ...</td>
264264
</tr>
265+
<tr>
266+
<td>types::array::ArrayBase&lt;Option&lt;~[u8]&gt;&gt;</td>
267+
<td>BYTEA[], BYTEA[][], ...</td>
268+
</tr>
265269
<tr>
266270
<td>types::array::ArrayBase&lt;Option&lt;i32&gt;&gt;</td>
267271
<td>INT4[], INT4[][], ...</td>

test.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,12 @@ fn test_boolarray_params() {
457457
test_array_params!("BOOL", false, "f", true, "t", true, "t");
458458
}
459459
460+
#[test]
461+
fn test_byteaarray_params() {
462+
test_array_params!("BYTEA", ~[0u8, 1], r#""\\x0001""#, ~[254u8, 255u8],
463+
r#""\\xfeff""#, ~[10u8, 11u8], r#""\\x0a0b""#);
464+
}
465+
460466
#[test]
461467
fn test_hstore_params() {
462468
macro_rules! make_map(

types/mod.rs

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ pub enum PostgresType {
8686
PgFloat8,
8787
/// BOOL[]
8888
PgBoolArray,
89+
/// BYTEA[]
90+
PgByteAArray,
8991
/// INT4[]
9092
PgInt4Array,
9193
/// INT8[]
@@ -136,6 +138,7 @@ impl PostgresType {
136138
FLOAT4OID => PgFloat4,
137139
FLOAT8OID => PgFloat8,
138140
BOOLARRAYOID => PgBoolArray,
141+
BYTEAARRAYOID => PgByteAArray,
139142
INT4ARRAYOID => PgInt4Array,
140143
INT8ARRAYOID => PgInt8Array,
141144
FLOAT4ARRAYOID => PgFloat4Array,
@@ -194,32 +197,38 @@ pub trait FromSql {
194197
}
195198

196199
trait RawFromSql {
197-
fn raw_from_sql<R: Reader>(raw: &mut R) -> Self;
200+
fn raw_from_sql<R: Reader>(len: uint, raw: &mut R) -> Self;
198201
}
199202

200203
macro_rules! raw_from_impl(
201204
($t:ty, $f:ident) => (
202205
impl RawFromSql for $t {
203-
fn raw_from_sql<R: Reader>(raw: &mut R) -> $t {
206+
fn raw_from_sql<R: Reader>(_len: uint, raw: &mut R) -> $t {
204207
raw.$f()
205208
}
206209
}
207210
)
208211
)
209212

210213
impl RawFromSql for bool {
211-
fn raw_from_sql<R: Reader>(raw: &mut R) -> bool {
214+
fn raw_from_sql<R: Reader>(_len: uint, raw: &mut R) -> bool {
212215
raw.read_u8() != 0
213216
}
214217
}
215218

219+
impl RawFromSql for ~[u8] {
220+
fn raw_from_sql<R: Reader>(len: uint, raw: &mut R) -> ~[u8] {
221+
raw.read_bytes(len)
222+
}
223+
}
224+
216225
raw_from_impl!(i32, read_be_i32)
217226
raw_from_impl!(i64, read_be_i64)
218227
raw_from_impl!(f32, read_be_f32)
219228
raw_from_impl!(f64, read_be_f64)
220229

221230
impl RawFromSql for Timespec {
222-
fn raw_from_sql<R: Reader>(raw: &mut R) -> Timespec {
231+
fn raw_from_sql<R: Reader>(_len: uint, raw: &mut R) -> Timespec {
223232
let t = raw.read_be_i64();
224233
let mut sec = t / USEC_PER_SEC + TIME_SEC_CONVERSION;
225234
let mut usec = t % USEC_PER_SEC;
@@ -248,7 +257,7 @@ macro_rules! from_raw_from_impl(
248257
($($expected:pat)|+, $t:ty) => (
249258
from_map_impl!($($expected)|+, $t, |buf| {
250259
let mut reader = BufReader::new(buf.as_slice());
251-
RawFromSql::raw_from_sql(&mut reader)
260+
RawFromSql::raw_from_sql(buf.len(), &mut reader)
252261
})
253262
)
254263
)
@@ -276,6 +285,8 @@ macro_rules! from_option_impl(
276285

277286
from_raw_from_impl!(PgBool, bool)
278287
from_option_impl!(bool)
288+
from_raw_from_impl!(PgByteA, ~[u8])
289+
from_option_impl!(~[u8])
279290
from_raw_from_impl!(PgInt4, i32)
280291
from_option_impl!(i32)
281292
from_raw_from_impl!(PgInt8, i64)
@@ -295,11 +306,6 @@ from_map_impl!(PgVarchar | PgText | PgCharN, ~str, |buf| {
295306
})
296307
from_option_impl!(~str)
297308

298-
from_map_impl!(PgByteA, ~[u8], |buf| {
299-
buf.clone()
300-
})
301-
from_option_impl!(~[u8])
302-
303309
from_map_impl!(PgJson, Json, |buf| {
304310
json::from_str(str::from_utf8(buf.as_slice())).unwrap()
305311
})
@@ -328,9 +334,9 @@ macro_rules! from_range_impl(
328334
0 => Exclusive,
329335
_ => Inclusive
330336
};
331-
rdr.read_be_i32();
332-
Some(RangeBound::new(RawFromSql::raw_from_sql(&mut rdr),
333-
type_))
337+
let len = rdr.read_be_i32() as uint;
338+
Some(RangeBound::new(
339+
RawFromSql::raw_from_sql(len, &mut rdr), type_))
334340
}
335341
_ => None
336342
};
@@ -340,9 +346,9 @@ macro_rules! from_range_impl(
340346
0 => Exclusive,
341347
_ => Inclusive
342348
};
343-
rdr.read_be_i32();
344-
Some(RangeBound::new(RawFromSql::raw_from_sql(&mut rdr),
345-
type_))
349+
let len = rdr.read_be_i32() as uint;
350+
Some(RangeBound::new(
351+
RawFromSql::raw_from_sql(len, &mut rdr), type_))
346352
}
347353
_ => None
348354
};
@@ -386,7 +392,8 @@ macro_rules! from_array_impl(
386392
if len < 0 {
387393
elements.push(None);
388394
} else {
389-
elements.push(Some(RawFromSql::raw_from_sql(&mut rdr)));
395+
elements.push(Some(RawFromSql::raw_from_sql(len as uint,
396+
&mut rdr)));
390397
}
391398
}
392399

@@ -398,6 +405,9 @@ macro_rules! from_array_impl(
398405
from_array_impl!(PgBoolArray, bool)
399406
from_option_impl!(ArrayBase<Option<bool>>)
400407

408+
from_array_impl!(PgByteAArray, ~[u8])
409+
from_option_impl!(ArrayBase<Option<~[u8]>>)
410+
401411
from_array_impl!(PgInt4Array, i32)
402412
from_option_impl!(ArrayBase<Option<i32>>)
403413

@@ -477,6 +487,16 @@ impl RawToSql for bool {
477487
}
478488
}
479489
490+
impl RawToSql for ~[u8] {
491+
fn raw_to_sql<W: Writer>(&self, w: &mut W) {
492+
w.write(self.as_slice())
493+
}
494+
495+
fn raw_size(&self) -> uint {
496+
self.len()
497+
}
498+
}
499+
480500
raw_to_impl!(i32, write_be_i32)
481501
raw_to_impl!(i64, write_be_i64)
482502
raw_to_impl!(f32, write_be_f32)
@@ -554,6 +574,8 @@ macro_rules! to_conversions_impl(
554574
555575
to_raw_to_impl!(PgBool, bool)
556576
to_option_impl!(PgBool, bool)
577+
to_raw_to_impl!(PgByteA, ~[u8])
578+
to_option_impl!(PgByteA, ~[u8])
557579
to_raw_to_impl!(PgInt4, i32)
558580
to_option_impl!(PgInt4, i32)
559581
to_raw_to_impl!(PgInt8, i64)
@@ -585,21 +607,13 @@ impl<'self> ToSql for &'self str {
585607
to_option_impl!(PgVarchar | PgText | PgCharN, ~str)
586608
to_option_impl_self!(PgVarchar | PgText | PgCharN, &'self str)
587609
588-
impl ToSql for ~[u8] {
589-
fn to_sql(&self, ty: &PostgresType) -> (Format, Option<~[u8]>) {
590-
check_types!(PgByteA, ty)
591-
(Binary, Some(self.to_owned()))
592-
}
593-
}
594-
595610
impl<'self> ToSql for &'self [u8] {
596611
fn to_sql(&self, ty: &PostgresType) -> (Format, Option<~[u8]>) {
597612
check_types!(PgByteA, ty)
598613
(Binary, Some(self.to_owned()))
599614
}
600615
}
601616
602-
to_option_impl!(PgByteA, ~[u8])
603617
to_option_impl_self!(PgByteA, &'self [u8])
604618
605619
impl ToSql for Json {
@@ -715,6 +729,9 @@ macro_rules! to_array_impl(
715729
to_array_impl!(PgBoolArray, BOOLOID, bool)
716730
to_option_impl!(PgBoolArray, ArrayBase<Option<bool>>)
717731
732+
to_array_impl!(PgByteAArray, BYTEAOID, ~[u8])
733+
to_option_impl!(PgByteAArray, ArrayBase<Option<~[u8]>>)
734+
718735
to_array_impl!(PgInt4Array, INT4OID, i32)
719736
to_option_impl!(PgInt4Array, ArrayBase<Option<i32>>)
720737

0 commit comments

Comments
 (0)