Skip to content

Instantly share code, notes, and snippets.

@ItsWendell
Created October 21, 2023 15:23
Show Gist options
  • Save ItsWendell/65a107c0f8de00fdd6e4f3935789ce5a to your computer and use it in GitHub Desktop.
Save ItsWendell/65a107c0f8de00fdd6e4f3935789ce5a to your computer and use it in GitHub Desktop.
Experimental / hacky custom drizzle column for PostGIS geometry (injection method)
export type GeometryTypes = {
Point: GeoJSON.Point;
LineString: GeoJSON.LineString;
Polygon: GeoJSON.Polygon;
MultiPoint: GeoJSON.MultiPoint;
MultiLineString: GeoJSON.MultiLineString;
MultiPolygon: GeoJSON.MultiPolygon;
GeometryCollection: GeoJSON.GeometryCollection;
};
/**
* Experimental custom type for PostGIS geometry, only supports Point and LineString.
*/
export const geometryType = <
TType extends GeoJSON.Geometry["type"] = GeoJSON.Geometry["type"],
T extends CustomTypeValues = CustomTypeValues,
>(
dbName: string,
fieldConfig?: T["config"] & { type: TType },
) => {
const type = fieldConfig?.type;
return customType<{
data: GeometryTypes[TType];
}>({
dataType() {
return type ? `geometry(${type},4326)` : "geometry";
},
toDriver(value) {
throw new Error("Not implemented");
},
fromDriver(value) {
try {
const data = JSON.parse(value as string);
if (type && data.type !== type) {
throw new Error(`Expected geometry type ${type}, got ${data.type}`);
}
return data as GeometryTypes[TType];
} catch (e) {
throw new Error(`Failed to parse geometry`, {
cause: e,
});
}
},
})(`public".ST_AsGeoJSON("${dbName}") as "${dbName}`, {
...fieldConfig,
});
};
@hauserkristof
Copy link

Hey @fvaldes33 !

This is great, thanks for sharing!

How to you use it for schema definitions and migration generation? That part is not working okay for me.

Cloud you please share more details?

Thank you,
Kristóf

@fvaldes33
Copy link

@hauserkristof - I am not. I usually write migrations manually. I am only using drizzle for the typesafe / orm api not to 100% manage my database schema.

The issue is probably the hack around how the name is generated in that custom type. there is an open PR to add a custom select in custom types that will allow you to use a normal column name instead of the ST_AsGeoJson wrapper.

@ItsWendell
Copy link
Author

@madebyfabian @hauserkristof @fvaldes33 I've also written an alternative implementation by parsing the actual values from the database:

https://gist.github.com/ItsWendell/38ebe96b34d00d9138ce23cc363d7009

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment