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

Access to column names for given repo in Repo instance #4

Open
lbialy opened this issue Jun 25, 2023 · 4 comments
Open

Access to column names for given repo in Repo instance #4

lbialy opened this issue Jun 25, 2023 · 4 comments

Comments

@lbialy
Copy link
Contributor

lbialy commented Jun 25, 2023

Hi,

I'm looking into how one can leverage work done by Magnum's reflection to help write future-proof queries in Repo subclasses. One thing that would be massively helpful would be if selectable and insertable columns (eElemNamesSql and ecElemNamesSql in RepoDefaults macros respectively) would be available on either RepoDefaults (one can always summon[RepoDefaults[...]]) or even better, on ImmutableRepo (selectable columns) and Repo (insertable columns). I imagine you could return them in a custom collection type (a wrapper over Vector maybe?) that has an overridden toString() so that it can format them correctly as in SqliteDbType:

    val selectKeys = eElemNamesSql.mkString(", ")
    val ecInsertKeys = ecElemNamesSql.mkString("(", ", ", ")")

You could expose that logic on DbType subtypes and then use it by catching proper DbType in macro just as you do now in RepoDefaults and passing it to the custom collection instance to format columns on interpolation. This would allow user to filter out columns on demand while still providing correct set of columns driven by the structure of actual scala case classes and not via flaky query strings.

What do you think? Would you accept a PR with such functionality?

@lbialy
Copy link
Contributor Author

lbialy commented Jun 25, 2023

Motivating example:

    def insertIgnoreDuplicates(insert: ProjectInsert)(using DbCon): Int =
      sql"""
         INSERT OR IGNORE INTO projects (organization, repository, logo)
         VALUES (${insert.organization}, ${insert.repository}, ${insert.logo})
         """.update.run()

could very well be:

    def insertIgnoreDuplicates(insert: ProjectInsert)(using DbCon): Int =
      sql"""
         INSERT OR IGNORE INTO projects $insertColumns
         VALUES ($insertParameters)
         """.update.run()

under the assumption that in scope of Repo subclass there would be an insertColumns value/method available and also insertParameters (where that would probably be DbCodec[EC].queryRepr). Probably, by the same logic, columns and parameters would be necessary too.

@AugustNagro
Copy link
Owner

That's a great idea, I will definitely accept a PR.

I also like the idea of adding such methods to ImmutableRepo.

@lbialy
Copy link
Contributor Author

lbialy commented Sep 2, 2023

This could be closed but it also can track the work necessary to actually include TableInfo in Repo/ImmutableRepo scopes. Given that this was the goal of this issue I will leave this open and when I have more time (and the compiler issue is fixed!) I'll dive into this again.

@AugustNagro
Copy link
Owner

Sounds good :)

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