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

feat: EXPOSED-368 Ordering on References #2083

Merged
merged 4 commits into from
Jun 3, 2024

Conversation

obabichevjb
Copy link
Collaborator

PR add the possibility to add sorting for one-to-many references. Usage looks like:

class User(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<User>(Users)
    ...
    val ratings by UserRating referrersOn UserRatings.user orderBy UserRatings.value
    ...
}

Open questions that I haven't yet resolved:

  1. It's not possible to create several references with different orders. For example, something like this would not work:
class User(id: EntityID<Int>) : IntEntity(id) {
   companion object : IntEntityClass<User>(Users)
   ...
   val ratingsByValue by UserRating referrersOn UserRatings.user orderBy UserRatings.value
   val ratingsById by UserRating referrersOn UserRatings.user orderBy UserRatings.id
   ...
}

The reason is the caching of referencing rules inside EntityClass::refDefinitions. Every time we try to add a reference to the same column, the cached one is returned.
Solution options:

  • let it be as it is. We may assume that user should not create references with different orders. But at the current moment there is no error handling, and if a user actually tries to add several references in different order, they will get unexpected behaviour (actually, the first created reference would be used every time)
  • extend cache with order and save inside cache not only per column, but also per sorting configuration. For me, it looks like a better solution if we need that caching.
  • do we need that caching? I mean, what is the purpose of this caching? Can a user now intentionally create two references to another entity and expect that it would be the same reference?
  1. There are 2 classes Referrers and OptionalReferrers, but to me one of them (for instance OptionalReference) looks redundant. They do the same thing and have only a small difference in field reference (in one case it has type Column<REF> in another Column<REF?>, but since REF is generic, it can be specified one level above. It will look like:
// Before
infix fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.optionalReferrersOn(
    column: Column<REF?>
) =
    registerRefRule(column) { OptionalReferrers<ID, Entity<ID>, TargetID, Target, REF>(column, this, true) }

// After
infix fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.optionalReferrersOn(
column: Column<REF?>
) =
registerRefRule(column) { Referrers<ID, Entity<ID>, TargetID, Target, REF?>(column, this, true) }

After that OptionalReferrers can be removed. The only reason to keep it I see is the semantic (previous variant is better readable from user perspective).

For now I created BaseReferrers to place common logic inside one class, but I can join all of these 3 classes (Referrers, OptionalReferrers, BaseReferrers) into one Referrers.

@obabichevjb obabichevjb requested review from e5l and bog-walk May 14, 2024 13:59
Copy link
Member

@bog-walk bog-walk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

via() (the InnerTableLink reference) also returns a SizedIterable that should be possible to order in the same way. Could this be added at the same time?

Comment on lines 118 to 119

abstract class BaseReferrers<ParentID : Comparable<ParentID>, in Parent : Entity<ParentID>, ChildID : Comparable<ChildID>, out Child : Entity<ChildID>, REF>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this switch cause any issue for the other reference classes that delegate to OptionalReferrers?

Also, is the plan to deprecate OptionalReferrers and then drop this new class after in favor of Referrers alone? If so, would it be better to just have duplicate code in the 2 existing classes, that way we'd only have to deprecate one class. Without having to introduce a new temporary class into the API.
Unless the plan is to push that second PR before this one is released, so BaseReferrers doesn't actually enter the API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was actually open question what is better to do, and the variant to mark OptionalReferrers as deprecated looks good to me.

In order to avoid one more class in API it's not a problem to inherit OptionalReferrers from Referrers (but the last one should be open). Pushed such a variant, but we can discuss it again.

@joc-a joc-a changed the title EXPOSED-368 Ordering on References feat: EXPOSED-368 Ordering on References May 22, 2024
…t for changed orderBy, add orderBy to InnerTableLink (`via()`)
@obabichevjb
Copy link
Collaborator Author

via() (the InnerTableLink reference) also returns a SizedIterable that should be possible to order in the same way. Could this be added at the same time?

Added ordering to InnerTableLink also. I tried to unify it somehow to make less duplication, but can not say I found a good variant without inheritance. I like the variant via delegation but in this case it's not easy to return this from the orderBy methods, so if you have any thoughts about how to unify the same part with orderBy methods I'd be glad to know about it.

@obabichevjb obabichevjb requested a review from bog-walk May 22, 2024 14:07
@e5l e5l requested a review from joc-a May 28, 2024 07:30
@obabichevjb obabichevjb requested a review from e5l May 28, 2024 08:58
Copy link
Member

@bog-walk bog-walk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just a typo in one of the KDocs.

@obabichevjb obabichevjb merged commit 313b9a9 into main Jun 3, 2024
5 checks passed
@obabichevjb obabichevjb deleted the obabichev/exposed-368-ordering-on-reference branch June 3, 2024 09:02
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

Successfully merging this pull request may close these issues.

None yet

3 participants