AugustNagro / magnum

A 'new look' for database access in Scala
Apache License 2.0
153 stars 10 forks source link

Future-Proof Queries Part 2 #11

Closed AugustNagro closed 1 year ago

AugustNagro commented 1 year ago

This MR builds on @lbialy 's https://github.com/AugustNagro/magnum/pull/8 .

Here's some examples.

object Schema:
  val car = DbSchema[Car, Car, Long]
  val person = DbSchema[PersonCreator, Person, Long]

def carsWithMinSpeed(minSpeed: Int)(using DbCon): Vector[Car] =
  val c = Schema.car
  sql"select ${c.all} from $c where ${c.topSpeed} > $minSpeed"
    .query[Car].run()

The .all selects the columns in the right order, so this should help with @EvgenyAfanasev 's https://github.com/AugustNagro/magnum/issues/2 .

For queries with multiple joins, you can use .alias(String) to avoid name conflicts.

val c = Schema.car.alias("c")
val p = Schema.person.alias("p")

sql"select ${c.all}, ${p.firstName} from $c join $p on ${p.id} = ${c.personId}"

This generates:

select c.model, c.id, ..., p.first_name from car c join person p on p.id = c.person_id

.insertColumns are available to help with inserting:

val p = Schema.person
val pc: PersonCreator = ???
sql"insert into $p ${p.insertColumns} values ($pc)"

I did remove the methods from Repo & RepoDefaults. Lmk if you still need / want them.

lbialy commented 1 year ago

nice!

lbialy commented 1 year ago

is this WIP or are you going to merge this as is?

AugustNagro commented 1 year ago

I think it's close.. letting a few more ideas percolate.

I just made some name changes and added class SqlLiteral. I'm also thinking of changing the name of DbSchema to something like TableInfo, since I'd like to have a schemaName(String) method, that works like

val user = TableInfo[UserCreator, User, Long].schema("my_qa_schema")
sql"SELECT * FROM $user".sqlString == "SELECT * FROM my_qa_schema.user"

Lmk if you have any other thoughts. Once this PR is merged I'll cut a release.

AugustNagro commented 1 year ago

Going to give another day or two then merge and release.

lbialy commented 1 year ago

It would be nice if there was a TableInfo available in scope of Repo/ImmutableRepo. To add custom .schema and .alias it would have to be overridden by user I guess. Let me know if that's something you'd consider. It's probably fine if user has to to this manually too.

AugustNagro commented 1 year ago

It would be nice if there was a TableInfo available in scope of Repo/ImmutableRepo

Do you have an idea on how that could be done while preserving TableInfo's structural typing?

I also removed the .schema method, since users can just put it in the @SqlName annotation on a table. And then the auto-generated queries pick it up too.

lbialy commented 1 year ago

I'll ask our macro wizards.

On Fri 28. Jul 2023 at 05:42, August Nagro @.***> wrote:

It would be nice if there was a TableInfo available in scope of Repo/ImmutableRepo

Do you have an idea on how that could be done while preserving TableInfo's structural typing?

I also removed the .schema method, since users can just put it in the @SqlName annotation on a table. And then the auto-generated queries pick it up too.

— Reply to this email directly, view it on GitHub https://github.com/AugustNagro/magnum/pull/11#issuecomment-1654947898, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACBVNUT7KTDGBPGW7J2EDGDXSMYKDANCNFSM6AAAAAA2MGGIBQ . You are receiving this because you were mentioned.Message ID: @.***>

lbialy commented 1 year ago

Ok, so our Macro Wizard, @prolativ, has spoken and shared his insights on this. He proposes that this refinement type could be piggybacked on RepoDefaults. This would in turn force genRepo and genImmutableRepo to be transparent inline givens and to compute that refinement type to include it as a type member of RepoDefaults. Then it could be used to power automatic TableInfo in Repo/ImmutableRepo.

lbialy commented 1 year ago

I'll try and poc that later today.

AugustNagro commented 1 year ago

Any luck @lbialy? If not we can just merge as is.

lbialy commented 1 year ago

Can you wait just a bit more with this? I'm a bit busy with another project atm.

AugustNagro commented 1 year ago

Sure, no problem.

On Mon, Aug 14, 2023, 11:15 PM Łukasz Biały @.***> wrote:

Can you wait just a bit more with this? I'm a bit busy with another project atm.

— Reply to this email directly, view it on GitHub https://github.com/AugustNagro/magnum/pull/11#issuecomment-1678473996, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQOKNQMADP6Z47VO3LJRXTXVMHZFANCNFSM6AAAAAA2MGGIBQ . You are receiving this because you authored the thread.Message ID: @.***>

lbialy commented 1 year ago

There's a compiler bug that prevents @prolativ's solution from working at the moment. We can always add this as an improvement later on. The skeleton of how that would work is on this branch in my fork: https://github.com/lbialy/magnum/tree/tables-in-repos https://github.com/AugustNagro/magnum/commit/24f626842a697be8f3a68f119315f908454f3359

It's your call.

AugustNagro commented 1 year ago

Sweet, that approach is what I tried too. Should we file the compiler bug, or is there already one out there?

lbialy commented 1 year ago

I believe Paweł Marks filed it on our behalf or will file it on Monday after a minimized example is done. Funnily enough, it sometimes work. Either way, transparent inline givens should preserve refinements in type members.

On Sat 19. Aug 2023 at 02:40, August Nagro @.***> wrote:

Sweet, that approach is what I tried too. Should we file the compiler bug, or is there already one out there?

— Reply to this email directly, view it on GitHub https://github.com/AugustNagro/magnum/pull/11#issuecomment-1684608467, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACBVNUXONO2UUKUYXDWGDDTXWADO7ANCNFSM6AAAAAA2MGGIBQ . You are receiving this because you were mentioned.Message ID: @.***>