Skip to content

Commit

Permalink
Add support for raw WKB DB queries
Browse files Browse the repository at this point in the history
  • Loading branch information
pka committed Aug 6, 2023
1 parent 8e6458c commit 9132a59
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 0 deletions.
16 changes: 16 additions & 0 deletions geozero/src/gpkg/geopackage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ impl<'de, T: FromWkb + Sized> Decode<'de, Sqlite> for wkb::Decode<T> {
}
}

impl sqlx::Type<Sqlite> for wkb::GpkgWkb {
fn type_info() -> SqliteTypeInfo {
<Vec<u8> as sqlx::Type<Sqlite>>::type_info()
}
}

impl<'de> Decode<'de, Sqlite> for wkb::GpkgWkb {
fn decode(value: SqliteValueRef<'de>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(wkb::GpkgWkb(Vec::new()));
}
let blob = <&[u8] as Decode<Sqlite>>::decode(value)?;
Ok(wkb::GpkgWkb(blob.to_vec()))
}
}

impl<T: GeozeroGeometry + Sized> sqlx::Type<Sqlite> for wkb::Encode<T> {
fn type_info() -> SqliteTypeInfo {
<Vec<u8> as sqlx::Type<Sqlite>>::type_info()
Expand Down
14 changes: 14 additions & 0 deletions geozero/src/postgis/postgis_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ impl<T: FromWkb + Sized> FromSql<'_> for wkb::Decode<T> {
}
}

impl FromSql<'_> for wkb::Ewkb {
fn from_sql(_ty: &Type, raw: &[u8]) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
Ok(wkb::Ewkb(raw.to_vec()))
}

fn from_sql_null(_ty: &Type) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
Ok(wkb::Ewkb(Vec::new()))
}

fn accepts(ty: &Type) -> bool {
matches!(ty.name(), "geography" | "geometry")
}
}

impl<T: GeozeroGeometry + Sized> ToSql for wkb::Encode<T> {
fn to_sql(
&self,
Expand Down
22 changes: 22 additions & 0 deletions geozero/src/postgis/postgis_sqlx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,28 @@ impl<'de, T: FromWkb + Sized> Decode<'de, Postgres> for wkb::Decode<T> {
}
}

impl sqlx::Type<Postgres> for wkb::Ewkb {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("geometry")
}
}

impl PgHasArrayType for wkb::Ewkb {
fn array_type_info() -> PgTypeInfo {
PgTypeInfo::with_name("_geometry")
}
}

impl<'de> Decode<'de, Postgres> for wkb::Ewkb {
fn decode(value: PgValueRef<'de>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(wkb::Ewkb(Vec::new()));
}
let blob = <&[u8] as Decode<Postgres>>::decode(value)?;
Ok(wkb::Ewkb(blob.to_vec()))
}
}

impl<T: GeozeroGeometry + Sized> sqlx::Type<Postgres> for wkb::Encode<T> {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("geometry")
Expand Down
7 changes: 7 additions & 0 deletions geozero/tests/geopackage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ async fn blob_query() -> Result<(), sqlx::Error> {
let wkt = wkb::GpkgWkb(row.0).to_wkt().unwrap();
assert_eq!(&wkt, "POINT(1.1 1.1)");

let row: (wkb::GpkgWkb,) = sqlx::query_as("SELECT geom FROM pt2d")
.fetch_one(&pool)
.await?;

let wkt = row.0.to_wkt().unwrap();
assert_eq!(&wkt, "POINT(1.1 1.1)");

Ok(())
}

Expand Down
8 changes: 8 additions & 0 deletions geozero/tests/postgis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ mod postgis_sqlx {
let wkt = wkb::Ewkb(row.0).to_wkt().expect("to_wkt failed");
assert_eq!(&wkt, "POLYGON((0 0,2 0,2 2,0 2,0 0))");

let row: (wkb::Ewkb,) =
sqlx::query_as("SELECT 'SRID=4326;POLYGON ((0 0, 2 0, 2 2, 0 2, 0 0))'::geometry")
.fetch_one(&pool)
.await?;

let wkt = row.0.to_wkt().expect("to_wkt failed");
assert_eq!(&wkt, "POLYGON((0 0,2 0,2 2,0 2,0 0))");

Ok(())
}

Expand Down

0 comments on commit 9132a59

Please sign in to comment.