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

Cascading Column Names for nested Case Classes. #3148

Open
jmpicnic opened this issue Dec 12, 2024 · 1 comment
Open

Cascading Column Names for nested Case Classes. #3148

jmpicnic opened this issue Dec 12, 2024 · 1 comment

Comments

@jmpicnic
Copy link

jmpicnic commented Dec 12, 2024

Version: 4.8.6
Module: quill-jdbc-zio
Database: postgres (but also in Mirror context)

Expected behavior

I am not sure if this is a problem, a design decision or my ignorance... so apologies if this is a dumb question. I have not found much information online. Any guidance would be greatly appreciated.

I would like to be able to use case classes with multiple nested classes without column name conflicts, this is not an uncommon situation in domains (e.g. case Person(name: String, home: Address, work: Address)) . The disambiguation should not depend on the nested case class Name but on the field name of the container class.

It seems that concatenating the "tree branch" of containment is already available somewhere b/c the nested query does precisely that already.

Actual behavior

When a case class has multiple nested classes embedded, the column names generated by querySchema and schemaMeta use only the name of the leaf field for the column, causing conflicts in column names.

Steps to reproduce the behavior

Here is the Scastie Snippet: https://scastie.scala-lang.org/jmpicnic/XKX7Cd8fSpyfi9nlpdzOvQ/1

import io.getquill.*

case class O(a: String, b: Long)
case class P(x: String, a: Int, b: Boolean, o1: O, o2: O)

val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal)

import ctx.*

// inline def probeSch: Quoted[EntityQuery[P]] = quote(querySchema[P]("p_table"))
implicit val pSchM: SchemaMeta[P] = schemaMeta[P]("P_TABLE")

val rs1 = ctx.run(query[P])
rs1.string(true)

val rs2 = ctx.run(query[P].nested)
rs2.string(true)

Workaround

None that I have been able to find in a way that would scale. It is possible to override column names in the schema definition, but on a one by one basis, which is impractical for commonly used "value classes" like Adddress, Unit Of Measure, etc... that get used all over the place.

I explored using a naming strategy but the input to the columns method is only the leaf name (it seems it would be easy to implement this in almost a backwards compatible way if the naming strategy method would have a signature as def columns(path: String*): String representing the tree path from the root, with the default being the current behavior.

I tried to dig into the SchemaMeta generation, but ended up being too much.

@getquill/maintainers

@jmpicnic
Copy link
Author

I would be willing to contribute to this feature with some guidance from the masters :-). Thanks a lot for great software.

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

1 participant