diff --git a/README.md b/README.md
index 6d1bea34..32c644d7 100644
--- a/README.md
+++ b/README.md
@@ -282,6 +282,10 @@ types. The driver currently supports the following conversions:
types::array::ArrayBase<Option<~str>> |
TEXT[], CHAR(n)[], VARCHAR[], TEXT[][], ... |
+
+ types::array::ArrayBase<Option<Json>> |
+ JSON[], JSON[][], ... |
+
types::array::ArrayBase<Option<i64>> |
INT8[], INT8[][], ... |
diff --git a/test.rs b/test.rs
index 1a1328a0..719662eb 100644
--- a/test.rs
+++ b/test.rs
@@ -796,3 +796,14 @@ fn test_dns_failure() {
_ => fail!("Expected error")
}
}
+
+#[test]
+fn test_jsonarray_params() {
+ test_array_params!("JSON",
+ json::from_str("[10, 11, 12]").unwrap(),
+ "\"[10,11,12]\"",
+ json::from_str(r#"{"a": 10, "b": null}"#).unwrap(),
+ r#""{\"a\": 10, \"b\": null}""#,
+ json::from_str(r#"{"a": [10], "b": true}"#).unwrap(),
+ r#""{\"a\": [10], \"b\": true}""#);
+}
diff --git a/types/mod.rs b/types/mod.rs
index 01cf3206..8191c4cb 100644
--- a/types/mod.rs
+++ b/types/mod.rs
@@ -30,6 +30,7 @@ static INT2OID: Oid = 21;
static INT4OID: Oid = 23;
static TEXTOID: Oid = 25;
static JSONOID: Oid = 114;
+static JSONARRAYOID: Oid = 199;
static FLOAT4OID: Oid = 700;
static FLOAT8OID: Oid = 701;
static BOOLARRAYOID: Oid = 1000;
@@ -147,6 +148,8 @@ make_postgres_type!(
TEXTOID => PgText,
#[doc="JSON"]
JSONOID => PgJson,
+ #[doc="JSON[]"]
+ JSONARRAYOID => PgJsonArray member PgJson,
#[doc="FLOAT4/REAL"]
FLOAT4OID => PgFloat4,
#[doc="FLOAT8/DOUBLE PRECISION"]
@@ -341,6 +344,14 @@ from_range_impl!(PgInt4Range, i32)
from_range_impl!(PgInt8Range, i64)
from_range_impl!(PgTsRange | PgTstzRange, Timespec)
+impl RawFromSql for Json {
+ fn raw_from_sql(len: uint, raw: &mut R) -> Json {
+ // TODO this should really use from_reader, but that seems to overshoot
+ let s = raw.read_bytes(len);
+ json::from_str(str::from_utf8_owned(s)).unwrap()
+ }
+}
+
macro_rules! from_map_impl(
($($expected:pat)|+, $t:ty, $blk:expr) => (
impl FromSql for Option<$t> {
@@ -379,10 +390,7 @@ from_raw_from_impl!(PgInt8, i64)
from_raw_from_impl!(PgFloat4, f32)
from_raw_from_impl!(PgFloat8, f64)
from_raw_from_impl!(PgUuid, Uuid)
-
-from_map_impl!(PgJson, Json, |buf| {
- json::from_str(str::from_utf8(buf.as_slice())).unwrap()
-})
+from_raw_from_impl!(PgJson, Json)
from_raw_from_impl!(PgTimestamp | PgTimestampTZ, Timespec)
from_raw_from_impl!(PgInt4Range, Range)
@@ -431,6 +439,7 @@ from_array_impl!(PgInt4Array, i32)
from_array_impl!(PgTextArray | PgCharNArray | PgVarcharArray, ~str)
from_array_impl!(PgInt8Array, i64)
from_array_impl!(PgTimestampArray | PgTimestampTZArray, Timespec)
+from_array_impl!(PgJsonArray, Json)
from_array_impl!(PgFloat4Array, f32)
from_array_impl!(PgFloat8Array, f64)
from_array_impl!(PgUuidArray, Uuid)
@@ -580,6 +589,12 @@ to_range_impl!(PgInt4Range, i32)
to_range_impl!(PgInt8Range, i64)
to_range_impl!(PgTsRange | PgTstzRange, Timespec)
+impl RawToSql for Json {
+ fn raw_to_sql(&self, raw: &mut W) {
+ self.to_writer(raw as &mut Writer)
+ }
+}
+
macro_rules! to_option_impl(
($($oid:pat)|+, $t:ty) => (
impl ToSql for Option<$t> {
@@ -629,6 +644,7 @@ macro_rules! to_raw_to_impl(
to_raw_to_impl!(PgBool, bool)
to_raw_to_impl!(PgByteA, ~[u8])
to_raw_to_impl!(PgVarchar | PgText | PgCharN, ~str)
+to_raw_to_impl!(PgJson, Json)
to_raw_to_impl!(PgChar, i8)
to_raw_to_impl!(PgInt2, i16)
to_raw_to_impl!(PgInt4, i32)
@@ -657,15 +673,6 @@ impl<'self> ToSql for &'self [u8] {
to_option_impl_self!(PgByteA, &'self [u8])
-impl ToSql for Json {
- fn to_sql(&self, ty: &PostgresType) -> (Format, Option<~[u8]>) {
- check_types!(PgJson, ty)
- (Text, Some(self.to_str().into_bytes()))
- }
-}
-
-to_option_impl!(PgJson, Json)
-
to_raw_to_impl!(PgTimestamp | PgTimestampTZ, Timespec)
to_raw_to_impl!(PgUuid, Uuid)
@@ -720,6 +727,7 @@ to_array_impl!(PgUuidArray, Uuid)
to_array_impl!(PgInt4RangeArray, Range)
to_array_impl!(PgTsRangeArray | PgTstzRangeArray, Range)
to_array_impl!(PgInt8RangeArray, Range)
+to_array_impl!(PgJsonArray, Json)
impl<'self> ToSql for HashMap<~str, Option<~str>> {
fn to_sql(&self, ty: &PostgresType) -> (Format, Option<~[u8]>) {