Skip to content

Commit aa37fe3

Browse files
committed
Json and Uuid support
cc rust-postgres#6
1 parent 2cc7f0f commit aa37fe3

2 files changed

Lines changed: 91 additions & 35 deletions

File tree

src/test.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
extern mod extra;
12
extern mod postgres;
23

4+
use extra::json;
5+
use extra::uuid::Uuid;
36
use std::f32;
47
use std::f64;
58

@@ -92,7 +95,7 @@ fn test_lazy_query() {
9295
}
9396
}
9497
95-
fn test_param_type<T: Eq+ToSql+FromSql>(sql_type: &str, values: &[T]) {
98+
fn test_type<T: Eq+ToSql+FromSql>(sql_type: &str, values: &[T]) {
9699
do test_in_transaction |trans| {
97100
trans.update("CREATE TABLE foo (
98101
id SERIAL PRIMARY KEY,
@@ -113,54 +116,67 @@ fn test_param_type<T: Eq+ToSql+FromSql>(sql_type: &str, values: &[T]) {
113116
114117
#[test]
115118
fn test_bool_params() {
116-
test_param_type("BOOL", [Some(true), Some(false), None]);
119+
test_type("BOOL", [Some(true), Some(false), None]);
117120
}
118121
119122
#[test]
120123
fn test_i16_params() {
121-
test_param_type("SMALLINT", [Some(0x0011i16), Some(-0x0011i16), None]);
124+
test_type("SMALLINT", [Some(0x0011i16), Some(-0x0011i16), None]);
122125
}
123126
124127
#[test]
125128
fn test_i32_params() {
126-
test_param_type("INT", [Some(0x00112233i32), Some(-0x00112233i32), None]);
129+
test_type("INT", [Some(0x00112233i32), Some(-0x00112233i32), None]);
127130
}
128131
129132
#[test]
130133
fn test_i64_params() {
131-
test_param_type("BIGINT", [Some(0x0011223344556677i64),
132-
Some(-0x0011223344556677i64), None]);
134+
test_type("BIGINT", [Some(0x0011223344556677i64),
135+
Some(-0x0011223344556677i64), None]);
133136
}
134137
135138
#[test]
136139
fn test_f32_params() {
137-
test_param_type("REAL", [Some(f32::infinity), Some(f32::neg_infinity),
138-
Some(1000.55), None]);
140+
test_type("REAL", [Some(f32::infinity), Some(f32::neg_infinity),
141+
Some(1000.55), None]);
139142
}
140143
141144
#[test]
142145
fn test_f64_params() {
143-
test_param_type("DOUBLE PRECISION", [Some(f64::infinity),
144-
Some(f64::neg_infinity),
145-
Some(10000.55), None]);
146+
test_type("DOUBLE PRECISION", [Some(f64::infinity),
147+
Some(f64::neg_infinity),
148+
Some(10000.55), None]);
146149
}
147150
148151
#[test]
149152
fn test_varchar_params() {
150-
test_param_type("VARCHAR", [Some(~"hello world"),
151-
Some(~"イロハニホヘト チリヌルヲ"), None]);
153+
test_type("VARCHAR", [Some(~"hello world"),
154+
Some(~"イロハニホヘト チリヌルヲ"), None]);
152155
}
153156
154157
#[test]
155158
fn test_text_params() {
156-
test_param_type("TEXT", [Some(~"hello world"),
157-
Some(~"イロハニホヘト チリヌルヲ"), None]);
159+
test_type("TEXT", [Some(~"hello world"),
160+
Some(~"イロハニホヘト チリヌルヲ"), None]);
158161
159162
}
160163
161164
#[test]
162165
fn test_bytea_params() {
163-
test_param_type("BYTEA", [Some(~[0u8, 1, 2, 3, 254, 255]), None]);
166+
test_type("BYTEA", [Some(~[0u8, 1, 2, 3, 254, 255]), None]);
167+
}
168+
169+
#[test]
170+
fn test_json_params() {
171+
test_type("JSON", [Some(json::from_str("[10, 11, 12]").unwrap()),
172+
Some(json::from_str("{\"f\": \"asd\"}").unwrap()),
173+
None])
174+
}
175+
176+
#[test]
177+
fn test_uuid_params() {
178+
test_type("UUID", [Some(Uuid::parse_string("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11").unwrap()),
179+
None])
164180
}
165181
166182
fn test_nan_param<T: Float+ToSql+FromSql>(sql_type: &str) {

src/types.rs

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
extern mod extra;
2+
3+
use extra::json;
4+
use extra::json::Json;
5+
use extra::uuid::Uuid;
16
use std::rt::io::Decorator;
27
use std::rt::io::extensions::{WriterByteConversions, ReaderByteConversions};
38
use std::rt::io::mem::{MemWriter, MemReader};
@@ -12,9 +17,11 @@ static INT8OID: Oid = 20;
1217
static INT2OID: Oid = 21;
1318
static INT4OID: Oid = 23;
1419
static TEXTOID: Oid = 25;
20+
static JSONOID: Oid = 114;
1521
static FLOAT4OID: Oid = 700;
1622
static FLOAT8OID: Oid = 701;
1723
static VARCHAROID: Oid = 1043;
24+
static UUIDOID: Oid = 2950;
1825

1926
pub enum Format {
2027
Text = 0,
@@ -29,7 +36,8 @@ pub fn result_format(ty: Oid) -> Format {
2936
INT2OID |
3037
INT4OID |
3138
FLOAT4OID |
32-
FLOAT8OID => Binary,
39+
FLOAT8OID |
40+
UUIDOID => Binary,
3341
_ => Text
3442
}
3543
}
@@ -98,8 +106,8 @@ from_option_impl!(f64)
98106
impl FromSql for Option<~str> {
99107
fn from_sql(ty:Oid, raw: &Option<~[u8]>) -> Option<~str> {
100108
check_oid!(VARCHAROID | TEXTOID, ty)
101-
do raw.chain_ref |buf| {
102-
Some(str::from_bytes(buf.as_slice()))
109+
do raw.map |buf| {
110+
str::from_bytes(buf.as_slice())
103111
}
104112
}
105113
}
@@ -113,6 +121,26 @@ impl FromSql for Option<~[u8]> {
113121
}
114122
from_option_impl!(~[u8])
115123

124+
impl FromSql for Option<Json> {
125+
fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<Json> {
126+
check_oid!(JSONOID, ty)
127+
do raw.map |buf| {
128+
json::from_str(str::from_bytes_slice(buf.as_slice())).unwrap()
129+
}
130+
}
131+
}
132+
from_option_impl!(Json)
133+
134+
impl FromSql for Option<Uuid> {
135+
fn from_sql(ty: Oid, raw: &Option<~[u8]>) -> Option<Uuid> {
136+
check_oid!(UUIDOID, ty)
137+
do raw.map |buf| {
138+
Uuid::from_bytes(buf.as_slice()).unwrap()
139+
}
140+
}
141+
}
142+
from_option_impl!(Uuid)
143+
116144
pub trait ToSql {
117145
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>);
118146
}
@@ -129,6 +157,18 @@ macro_rules! to_option_impl(
129157
}
130158
}
131159
}
160+
);
161+
(self, $($oid:ident)|+, $t:ty) => (
162+
impl<'self> ToSql for Option<$t> {
163+
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
164+
check_oid!($($oid)|+, ty)
165+
166+
match *self {
167+
None => (Text, None),
168+
Some(ref val) => val.to_sql(ty)
169+
}
170+
}
171+
}
132172
)
133173
)
134174

@@ -173,16 +213,7 @@ impl<'self> ToSql for &'self str {
173213
}
174214

175215
to_option_impl!(VARCHAROID | TEXTOID, ~str)
176-
177-
impl<'self> ToSql for Option<&'self str> {
178-
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
179-
check_oid!(VARCHAROID | TEXTOID, ty)
180-
match *self {
181-
None => (Text, None),
182-
Some(val) => val.to_sql(ty)
183-
}
184-
}
185-
}
216+
to_option_impl!(self, VARCHAROID | TEXTOID, &'self str)
186217

187218
impl<'self> ToSql for &'self [u8] {
188219
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
@@ -192,13 +223,22 @@ impl<'self> ToSql for &'self [u8] {
192223
}
193224

194225
to_option_impl!(BYTEAOID, ~[u8])
226+
to_option_impl!(self, BYTEAOID, &'self [u8])
195227

196-
impl<'self> ToSql for Option<&'self [u8]> {
228+
impl ToSql for Json {
197229
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
198-
check_oid!(BYTEAOID, ty)
199-
match *self {
200-
None => (Text, None),
201-
Some(val) => val.to_sql(ty)
202-
}
230+
check_oid!(JSONOID, ty)
231+
(Text, Some(self.to_str().into_bytes()))
232+
}
233+
}
234+
235+
to_option_impl!(JSONOID, Json)
236+
237+
impl ToSql for Uuid {
238+
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
239+
check_oid!(UUIDOID, ty)
240+
(Binary, Some(self.to_bytes().to_owned()))
203241
}
204242
}
243+
244+
to_option_impl!(UUIDOID, Uuid)

0 commit comments

Comments
 (0)