Support geo types with georust/geo

This commit is contained in:
kestred 2017-03-10 16:33:43 -07:00
parent 253613111d
commit efbf30c4fe
6 changed files with 91 additions and 0 deletions

View File

@ -253,6 +253,20 @@ types. The driver currently supports the following conversions:
(<a href="#optional-features">optional</a>)
</td>
<td>MACADDR</td>
</tr
<tr>
<td>
<a href="https://github.com/georust/rust-geo">geo::Point&lt;f64&gt;</a>
(<a href="#optional-features">optional</a>)
</td>
<td>POINT</td>
</tr>
<tr>
<td>
<a href="https://github.com/georust/rust-geo">geo::Bbox&lt;f64&gt;</a>
(<a href="#optional-features">optional</a>)
</td>
<td>BOX</td>
</tr>
</tbody>
</table>
@ -316,3 +330,13 @@ and `FromSql` implementations for `bit-vec`'s `BitVec` type.
[MACADDR](http://www.postgresql.org/docs/9.4/static/datatype-net-types.html#DATATYPE-MACADDR)
support is provided optionally by the `with-eui48` feature, which adds `ToSql`
and `FromSql` implementations for `eui48`'s `MacAddress` type.
### POINT type
[POINT](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6799)
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo`'s `Point` type.
### BOX type
[BOX](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6883)
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo`'s `Bbox` type.

View File

@ -10,6 +10,7 @@ repository = "https://github.com/sfackler/rust-postgres"
with-bit-vec = ["bit-vec"]
with-chrono = ["chrono"]
with-eui48 = ["eui48"]
with-geo = ["geo"]
with-rustc-serialize = ["rustc-serialize"]
with-serde_json = ["serde_json"]
with-time = ["time"]
@ -24,6 +25,7 @@ postgres-protocol = "0.2"
bit-vec = { version = "0.4", optional = true }
chrono = { version = "0.3", optional = true }
eui48 = { version = "0.1", optional = true }
geo = { version = "0.4", optional = true }
rustc-serialize = { version = "0.3", optional = true }
serde_json = { version = "0.9", optional = true }
time = { version = "0.1.14", optional = true }

View File

@ -0,0 +1,61 @@
extern crate geo;
use postgres_protocol::types;
use self::geo::{Bbox, Point};
use std::error::Error;
use types::{FromSql, ToSql, IsNull, Type};
impl FromSql for Point<f64> {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> {
if raw.len() != 16 {
return Err("invalid message length".into());
}
let x = types::float8_from_sql(&raw[0..8])?;
let y = types::float8_from_sql(&raw[8..16])?;
Ok(Point::new(x, y))
}
accepts!(Type::Point);
}
impl ToSql for Point<f64> {
fn to_sql(&self, _: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
types::float8_to_sql(self.x(), out);
types::float8_to_sql(self.y(), out);
Ok(IsNull::No)
}
accepts!(Type::Point);
to_sql_checked!();
}
impl FromSql for Bbox<f64> {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> {
if raw.len() != 32 {
return Err("invalid message length".into());
}
let xmax = types::float8_from_sql(&raw[0..8])?;
let ymax = types::float8_from_sql(&raw[8..16])?;
let xmin = types::float8_from_sql(&raw[16..24])?;
let ymin = types::float8_from_sql(&raw[24..32])?;
Ok(Bbox{xmax: xmax, ymax: ymax, xmin: xmin, ymin: ymin})
}
accepts!(Type::Box);
}
impl ToSql for Bbox<f64> {
fn to_sql(&self, _: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
types::float8_to_sql(self.xmax, out);
types::float8_to_sql(self.ymax, out);
types::float8_to_sql(self.xmin, out);
types::float8_to_sql(self.ymin, out);
Ok(IsNull::No)
}
accepts!(Type::Box);
to_sql_checked!();
}

View File

@ -73,6 +73,8 @@ mod serde_json;
mod chrono;
#[cfg(feature = "with-eui48")]
mod eui48;
#[cfg(feature = "with-geo")]
mod geo;
mod special;
mod type_gen;

View File

@ -24,6 +24,7 @@ path = "tests/test.rs"
with-bit-vec = ["postgres-shared/with-bit-vec"]
with-chrono = ["postgres-shared/with-chrono"]
with-eui48 = ["postgres-shared/with-eui48"]
with-geo = ["postgres-shared/with-geo"]
with-rustc-serialize = ["postgres-shared/with-rustc-serialize"]
with-serde_json = ["postgres-shared/with-serde_json"]
with-time = ["postgres-shared/with-time"]

View File

@ -13,6 +13,7 @@ keywords = ["database", "postgres", "postgresql", "sql", "async"]
with-bit-vec = ["postgres-shared/with-bit-vec"]
with-chrono = ["postgres-shared/with-chrono"]
with-eui48 = ["postgres-shared/with-eui48"]
with-geo = ["postgres-shared/with-geo"]
with-rustc-serialize = ["postgres-shared/with-rustc-serialize"]
with-serde_json = ["postgres-shared/with-serde_json"]
with-time = ["postgres-shared/with-time"]