Description
First, this is an amazing project! Thanks so much for maintaining it.
Something I get nervous about is accidentally putting the right type of Haskell data into the wrong column in the database, or getting the right type of data from the wrong column in the database. For instance, assuming a table like:
CREATE TABLE foo (
bar character varying NOT NULL,
baz character varying NOT NULL
);
And some Haskell definitions:
newtype Bar
= Bar Text
instance PGColumn "character varying" Bar where
...
instance PGParameter "character varying" Bar where
...
newtype Baz
= Baz Text
instance PGColumn "character varying" Baz where
...
instance PGParameter "character varying" Baz where
...
data Foo
= Foo
{ bar :: Bar
, baz :: Baz
}
There's nothing that really stops me from writing a query where the fields are mixed up, like:
getFoos conn = do
foos <- pgQuery conn [pgSQL| SELECT bar, baz FROM foo |]
pure $ go <$> foos
where
go :: (Baz, Bar) -> Foo
go (baz, bar) = Foo {..}
Everything type checks on the Haskell side, and it's a valid SQL expression. But, I've asked for the values from foo.bar
and foo.baz
–in that order–in SQL. Since both are varchars, the instances can be found in either order on the Haskell side. And a small typo has led to the data being wrong.
Do you have any thoughts on how to mitigate the chance for mistakes here? My first thought was to somehow associate the types in Foo
with the column names in the table foo
. Is that feasible? I would imagine that you'd need an additional type class and a different quasi quoter in order to handle that. But I haven't actually looked at anything yet. That might also be more complex than need be.