Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to work with composite field #4

Open
qnikst opened this issue Dec 5, 2019 · 2 comments
Open

How to work with composite field #4

qnikst opened this issue Dec 5, 2019 · 2 comments

Comments

@qnikst
Copy link

qnikst commented Dec 5, 2019

In my current project I have a decoder functions, decodeEntity :: Result A that decodes some columns, then I can write more complex decoder as:

   entity <- decodeEntity
   something <- HD.column ..
   pure Out{..}

But when statement returns big tuple I can no longer reuse the same parser. Is there a way to achieve the same with hasql-th?

@nikita-volkov
Copy link
Owner

Seems like it's a row decoder that you're describing here, so I'll assume that you meant decodeEntity :: Row A.

hasql-th establishes an approach where you don't use codecs at all. So it's not clear what you'd like to be reusing. Is your case where you have a record with nested records in its fields and you're looking for ways to automate on its construction from a flat tuple?

If I understood you correctly, it seems like a combination of "tuple" and "tuple-th" libraries could be of help, in particular, the uncurryN and splitTupleAt functions.

It also seems like we may need to implement a more general utility than splitTupleAt. Something that would do multiple splits on a tuple in one go.

@qnikst
Copy link
Author

qnikst commented Dec 6, 2019

So assume the following queries with hasql

example1 :: HS.Statement Int64 Entry
example1 = HS.Statement sql encoder decoder False where
   sql = "select id, name, phone from book where district_id=$1"
   encoder = (HE.column.HE.nonNullable) HE.int8
   decoder = HD.rowVector $ decodeEntry

example1_2 :: HS.Statement Int64 Entry
example1_2 = HS.Statement sql encoder decoder False where
   sql = [hasql|
     select a.id, b.id, b.name, b.phone
     from a inner join book on b.a_id = a.id
     left join c on d.id=b.district_id where a.id=$1 |]
   encoder = (HE.column.HE.nonNullable) HE.int8
   decoder = HD.rowVector $ (,,) <$> decodeA <*> decodeEntry <*> decodeB

Here I was able to use the same function that converts columns {b.id, b.name, b.phone} into my business entity. With some trickery it's possible to result that in aggregation that return composite field row(b.id, b.name, b.phone). Such reuse is very useful especially when you put more logic in decoding (i.e. field in business logic structure is a function from many columns).

With hasql-th I was similar experience, having a function from a tuple I want to reuse that in rmap of different queries. I see that I can have similar experience with TupleTH package, especially if I introduce more general ones, but I'm not sure that experience. I'll need to try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants