ihp icon indicating copy to clipboard operation
ihp copied to clipboard

ability to `select` 1-n fields of a model in query builder?

Open CSchank opened this issue 3 years ago • 2 comments

Currently, you always have to select * when using the query builder, then extract what you'd like in Haskell land. Sometimes I just want to select, say, a user's email. It seems like it would be more efficient to handle this in SQL land so you're not deserializing the whole thing just to get one or two fields. Here's my proposal:

email <- query @User 
        |> filterWhere (#id, userId)
        |> select #email
        |> fetch

Here, email :: Text.

And this could be used for multiple fields too perhaps (not sure if the tuple syntax can be made to work or not... open to suggestions):

(email, password) <- query @User 
        |> filterWhere (#id, userId)
        |> select (#email, #passwordHash)
        |> fetch

Here, email, password :: Text.

This would also work for lists of users:

emails <- query @User 
        |> filterWhereIn (#id, userIds)
        |> select #email
        |> fetch

Here, emails :: [Text].

emailsAndPasswords <- query @User 
        |> filterWhereIn (#id, userIds)
        |> select (#email, #passwordHash)
        |> fetch

Here, emailsAndPasswords :: [(Text, Text)].

Is something like this possible / desirable?

CSchank avatar Aug 18 '21 20:08 CSchank

This absolutely seems possible and is something I would love to have. Thinking of 50+ fields in a large record being parsed and assigned and taking up memory potentially hundreds of times every request when all we need is an ID is a scary thought!!

One issue with the tuple approach is the inability (as far as I'm aware) to construct arbitrarily large tuples at the type level, which would be needed for select (#email, #passwordHash, ...) . We could define cases for up to 10 records or something like that which should work fine though!

zacwood9 avatar Aug 27 '21 02:08 zacwood9

Agreed! Even network bandwidth on a remote database could theoretically become a factor for large responses.

I think Haskell's built-in tuples go up to something like 13 or 14, which I think would be more than enough for our purposes. I think there are packages which extend this further, though I could be mistaken.

CSchank avatar Aug 27 '21 03:08 CSchank