Skip to content

Associating Haskell fields with table columns #3

Open
@joneshf

Description

@joneshf

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions