Skip to content

Commit

Permalink
docs: EXPOSED-159 Add KDocs for EntityClass reference functions
Browse files Browse the repository at this point in the history
Add KDocs to EntityClass infix reference functions

Edit website docs to match updated Wiki
  • Loading branch information
bog-walk committed Aug 29, 2023
1 parent af6bdb1 commit 6df57b2
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 6df57b2

Please sign in to comment.