Skip to content

Commit

Permalink
docs: EXPOSED-159 Add KDocs for EntityClass reference functions (JetB…
Browse files Browse the repository at this point in the history
…rains#1848)

Add KDocs to EntityClass infix reference functions

Edit website docs to match updated Wiki
  • Loading branch information
bog-walk authored and saral committed Oct 3, 2023
1 parent a8ba014 commit f21e01d
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 8 deletions.
28 changes: 20 additions & 8 deletions documentation-website/Writerside/topics/Deep-Dive-into-DAO.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,33 +81,33 @@ movie.delete()
### many-to-one reference
Let's say you have this table:
```kotlin
object Users: IntIdTable() {
object Users : IntIdTable() {
val name = varchar("name", 50)
}
class User(id: EntityID<Int>): IntEntity(id) {
class User(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<User>(Users)
var name by Users.name
}
```
And now you want to add a table referencing this table (and other tables!):
```kotlin
object UserRatings: IntIdTable() {
object UserRatings : IntIdTable() {
val value = long("value")
val film = reference("film", StarWarsFilms)
val user = reference("user", Users)
}
class UserRating(id: EntityID<Int>): IntEntity(id) {
class UserRating(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<UserRating>(UserRatings)
var value by UserRatings.value
var film by StarWarsFilm referencedOn UserRatings.film // use referencedOn for normal references
var user by User referencedOn UserRatings.user
}
```
Now you can get the film for a rating in the same way you would get any other field:
Now you can get the film for a `UserRating` object, `filmRating`, in the same way you would get any other field:
```kotlin
filmRating.film // returns a StarWarsFilm object
```
Now if you wanted to get all the ratings for a film, you could do that by using the `FilmRating.find` function, but what is much easier is to just add a `referrersOn` field to the StarWarsFilm class:
Now if you wanted to get all the ratings for a film, you could do that by using the `filmRating.find` function, but it is much easier to just add a `referrersOn` field to the `StarWarsFilm` class:
```kotlin
class StarWarsFilm(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<StarWarsFilm>(StarWarsFilms)
Expand All @@ -116,10 +116,22 @@ class StarWarsFilm(id: EntityID<Int>) : IntEntity(id) {
...
}
```
You can call:
You can then access this field on a `StarWarsFilm` object, `movie`:
```kotlin
movie.ratings // returns all UserRating objects with this movie as film
```
Now imagine a scenario where a user only ever rates a single film. If you want to get the single rating for that user, you can add a `backReferencedOn` field to the `User` class to access the `UserRating` table data:
```kotlin
class User(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<User>(Users)
...
val rating by UserRating backReferencedOn UserRatings.user // make sure to use val and backReferencedOn
}
```
You can then access this field on a `User` object, `user1`:
```kotlin
user1.rating // returns a UserRating object
```
### Optional reference
You can also add an optional reference:
```kotlin
Expand All @@ -135,7 +147,7 @@ class UserRating(id: EntityID<Int>): IntEntity(id) {
...
}
```
Now `secondUser` will be a nullable field, and you should use `optionalReferrersOn` instead of `referrersOn` to get all the ratings for a `secondUser`.
Now `secondUser` will be a nullable field, and `optionalReferrersOn` should be used instead of `referrersOn` to get all the ratings for a `secondUser`.

```kotlin
class User(id: EntityID<Int>): IntEntity(id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,46 +294,138 @@ abstract class EntityClass<ID : Comparable<ID>, out T : Entity<ID>>(
private inline fun <reified R : Any> registerRefRule(column: Column<*>, ref: () -> R): R =
refDefinitions.getOrPut(column to R::class, ref) as R

/**
* Registers a reference as a field of the child entity class, which returns a parent object of this `EntityClass`.
*
* The reference should have been defined by the creation of a [column] using `reference()` on the child table.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Child
*/
infix fun <REF : Comparable<REF>> referencedOn(column: Column<REF>) = registerRefRule(column) { Reference(column, this) }

/**
* Registers an optional reference as a field of the child entity class, which returns a parent object of
* this `EntityClass`.
*
* The reference should have been defined by the creation of a [column] using either `optReference()` or
* `reference().nullable()` on the child table.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Post
*/
infix fun <REF : Comparable<REF>> optionalReferencedOn(column: Column<REF?>) = registerRefRule(column) { OptionalReference(column, this) }

/**
* Registers a reference as an immutable field of the parent entity class, which returns a child object of
* this `EntityClass`.
*
* The reference should have been defined by the creation of a [column] using `reference()` on the child table.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTestsData.YEntity
*/
infix fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.backReferencedOn(
column: Column<REF>
):
ReadOnlyProperty<Entity<ID>, Target> = registerRefRule(column) { BackReference(column, this) }

/**
* Registers a reference as an immutable field of the parent entity class, which returns a child object of
* this `EntityClass`.
*
* The reference should have been defined by the creation of a [column] using `reference()` on the child table.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTestsData.YEntity
*/
@JvmName("backReferencedOnOpt")
infix fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.backReferencedOn(
column: Column<REF?>
):
ReadOnlyProperty<Entity<ID>, Target> = registerRefRule(column) { BackReference(column, this) }

/**
* Registers an optional reference as an immutable field of the parent entity class, which returns a child object of
* this `EntityClass`.
*
* The reference should have been defined by the creation of a [column] using either `optReference()` or
* `reference().nullable()` on the child table.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Student
*/
infix fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.optionalBackReferencedOn(
column: Column<REF>
) =
registerRefRule(column) { OptionalBackReference<TargetID, Target, ID, Entity<ID>, REF>(column as Column<REF?>, this) }

/**
* Registers an optional reference as an immutable field of the parent entity class, which returns a child object of
* this `EntityClass`.
*
* The reference should have been defined by the creation of a [column] using either `optReference()` or
* `reference().nullable()` on the child table.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Student
*/
@JvmName("optionalBackReferencedOnOpt")
infix fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.optionalBackReferencedOn(
column: Column<REF?>
) =
registerRefRule(column) { OptionalBackReference<TargetID, Target, ID, Entity<ID>, REF>(column, this) }

/**
* Registers a reference as an immutable field of the parent entity class, which returns a collection of
* child objects of this `EntityClass` that all reference the parent.
*
* The reference should have been defined by the creation of a [column] using `reference()` on the child table.
*
* By default, this also stores the loaded entities to a cache.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityHookTestData.Country
*/
infix fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.referrersOn(column: Column<REF>) =
registerRefRule(column) { Referrers<ID, Entity<ID>, TargetID, Target, REF>(column, this, true) }

/**
* Registers a reference as an immutable field of the parent entity class, which returns a collection of
* child objects of this `EntityClass` that all reference the parent.
*
* The reference should have been defined by the creation of a [column] using `reference()` on the child table.
*
* Set [cache] to `true` to also store the loaded entities to a cache.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.School
*/
fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.referrersOn(
column: Column<REF>,
cache: Boolean
) =
registerRefRule(column) { Referrers<ID, Entity<ID>, TargetID, Target, REF>(column, this, cache) }

/**
* Registers an optional reference as an immutable field of the parent entity class, which returns a collection of
* child objects of this `EntityClass` that all reference the parent.
*
* The reference should have been defined by the creation of a [column] using either `optReference()` or
* reference().nullable()` on the child table.
*
* By default, this also stores the loaded entities to a cache.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Category
*/
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) }

/**
* Registers an optional reference as an immutable field of the parent entity class, which returns a collection of
* child objects of this `EntityClass` that all reference the parent.
*
* The reference should have been defined by the creation of a [column] using either `optReference()` or
* `reference().nullable()` on the child table.
*
* Set [cache] to `true` to also store the loaded entities to a cache.
*
* @sample org.jetbrains.exposed.sql.tests.shared.entities.EntityTests.Student
*/
fun <TargetID : Comparable<TargetID>, Target : Entity<TargetID>, REF : Comparable<REF>> EntityClass<TargetID, Target>.optionalReferrersOn(
column: Column<REF?>,
cache: Boolean = false
Expand Down

0 comments on commit f21e01d

Please sign in to comment.