typelevel / skunk

A data access library for Scala + Postgres.
https://typelevel.org/skunk/
MIT License
1.56k stars 157 forks source link

SQL DSL & Skunk #501

Open epifab opened 3 years ago

epifab commented 3 years ago

Hi, and thanks for your great effort. I'm working on revamping this project https://github.com/epifab/tydal (a typesafe SQL DSL for Postgres) for Scala 3, effectively ditching things like shapeless. One of the things I also wanted to get rid of is JDBC, so I thought wouldn't it be great if Tydal was actually built on top of Skunk? One idea could be to interact at a very high level, having Tydal building instances of Query[_, _] and Command[_], which might work and surely something worth exploring. Do you think this is the right approach, or is a lower level interaction possible? Full spoiler: I haven't checked out Skunk yet, and I don't know much about its modules and architecture, but I thought I'd ask your opinion before getting deep into it. Thanks in advance!

tpolecat commented 3 years ago

Hi, yes, it seems totally reasonable for Tydal to construct instances of Query and Command. Both are just case classes with public constructors, nothing fancy.

Note that the doc is all for Scala 2 at the moment. In Scala 2 you compose encoders/decoders/codecs (which your library will need to do) with ~ and end up with a left-leaning HList of types, like Encoder[(((A, B), C), D)] which you can decompose with ~ so you never see the nesting structure unless you squint. But in Scala 3 you compose encoders/decoders/codecs with *: and end up with a tuple of types, like Encoder[(A, B, C, D)] (which in Scala 3 is shorthand for Encoder[A *: B *: C *: D *: EmptyTuple]) and it's much much cleaner. So be sure you take advantage of the *: tupling behavior (i.e., avoid ~ because it will go away eventually).

Let me know if you run into trouble! Looks like a fun project.

tpolecat commented 3 years ago

Also if you check out my Scala Days talk (linked on the front page of the doc site) it will explain the architecture a bit. Since what you're doing is kind of superficial from Skunk's POV (ultimately it's just very a fancy constructor) it may not really matter but you might find it interesting.

epifab commented 3 years ago

I was actually in the audience at your talk! :) very interesting. I noticed the ~ and was already considering a workaround, because as you say I'm taking full advantage of the new generic programming features of Scala 3. what's the plan for moving away from ~? Will you build a different branch for scala 3 or how are you going to maintain backwards compatibility?

epifab commented 3 years ago

hi @tpolecat, I made good progresses on Tydal (you can check out a working example here). One issue that I noticed is that gmap wouldn't work as I'm decoding results into a flat tuple. On one hand I like your suggestion not to use ~, on the other hand I'd like gmap to work. Would you consider making gmap capable of dealing with a standard tuple? I guess it'll need some shapeless generic, but I think it should be feasible. I'm happy to work on a PR when I have the time if you think it's a good idea.

tpolecat commented 3 years ago

In Scala 3 use pmap. The example is cool.

tpolecat commented 3 years ago

See https://github.com/tpolecat/skunk/blob/main/modules/core/src/main/scala-3/syntax/DecoderOps.scala#L16-L20

epifab commented 2 years ago

awesome! I didn't realise that was already available. would it make sense to have it at Query level too?