From 7cb7d43222910a0d8d6bbe5cf7e6e797f955ef25 Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Mon, 30 Sep 2024 16:04:45 +0200 Subject: [PATCH 1/9] extend docs for defining entity instances and add links to the CRUD operations topic --- .../topics/DAO-CRUD-Operations.topic | 8 +++-- .../Writerside/topics/DAO-Table-Types.topic | 36 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic index 975a60c788..93e01ef9dc 100644 --- a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic +++ b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic @@ -10,6 +10,10 @@ CRUD (Create, Read, Update, Delete) are the four basic operations supported by any database. This section demonstrates how to perform SQL CRUD operations using Exposed's DAO (Data Access Object) API.

+

+ These operations can be performed directly through the methods and properties of the Entity class + associated with the table. For more information, see . +

To create a new table row, use the new function on the entity class: @@ -22,8 +26,8 @@ }

- In the above example StarWarsFilm would be the entity instance linked to the StarWarsFilms table. - For more information, see . + In the above example StarWarsFilm would be the entity instance linked to + the StarWarsFilms table.

To provide a manual id value to a new entity, pass the value as an argument to the id parameter: diff --git a/documentation-website/Writerside/topics/DAO-Table-Types.topic b/documentation-website/Writerside/topics/DAO-Table-Types.topic index 4c6a91aef7..c97432ca3e 100644 --- a/documentation-website/Writerside/topics/DAO-Table-Types.topic +++ b/documentation-website/Writerside/topics/DAO-Table-Types.topic @@ -50,7 +50,7 @@

The following example represents a table with custom columns sequel_id, name, and director:

- +

The IntIdTable class automatically generates an auto-incrementing integer id @@ -66,7 +66,17 @@

- An entity instance or a row in the table is defined as a class instance: + Representing database tables as Kotlin objects ensures type safety and allows you to work with database + records just like regular Kotlin objects, taking full advantage of Kotlin's language features. +

+

+ Any IdTable needs to be associated with an Entity, because every database record + in this table needs to be mapped to an Entity instance, identified by its primary key. +

+

+ An entity instance is defined as a class. + For example, given the above table definition of StarWarsFilms, + the corresponding entity class can be defined as follows:

) : IntEntity(id) { @@ -77,6 +87,28 @@ var director by StarWarsFilms.director } ]]> + +
  • + Since the StarWarsFilms table is an IntIdTable, the StarWarsFilm class extends from IntEntity, + which indicates that the id and primary key of the StarWarsFilm table is of type Int. +
  • +
  • + The companion object block defines an EntityClass which is responsible for maintaining + the relation between the StarWarsFilm class and the actual table object, StarWarsFilms. +
  • +
  • + Each column in the table is represented as a property in the class, where the by keyword + ensures the data is fetched or updated from the corresponding column when accessed. +
  • +
    +

    + Once the entity class is defined, instances of this class allow you to manipulate individual records + from the corresponding table. This could involve + creating a new record, + retrieving a row based on its primary key, + updating values, or + deleting records. +

    From c2315c266bc64c2e80ec356cb01923ef4c633dbc Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Tue, 1 Oct 2024 14:27:40 +0200 Subject: [PATCH 2/9] extend exposed-dao code example and add README files --- .../Writerside/snippets/README.md | 39 ++++++ .../Writerside/snippets/exposed-dao/README.md | 11 ++ .../src/main/kotlin/org/example/App.kt | 120 +++++++++++++++++- .../org/example/entities/DirectorEntity.kt | 12 ++ .../example/entities/StarWarsFilmEntity.kt | 13 ++ .../kotlin/org/example/entities/UserEntity.kt | 11 ++ .../org/example/entities/UserRatingEntity.kt | 13 ++ .../kotlin/org/example/tables/CitiesTable.kt | 7 + .../example/tables/CustomColumnTypeTable.kt | 12 ++ .../org/example/tables/DirectorsTable.kt | 13 ++ .../StarWarsFilmsTable.kt} | 2 +- .../org/example/tables/UserRatingsTable.kt | 9 ++ .../kotlin/org/example/tables/UsersTable.kt | 8 ++ 13 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 documentation-website/Writerside/snippets/README.md create mode 100644 documentation-website/Writerside/snippets/exposed-dao/README.md create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt rename documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/{StarWarsFilms.kt => tables/StarWarsFilmsTable.kt} (91%) create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt diff --git a/documentation-website/Writerside/snippets/README.md b/documentation-website/Writerside/snippets/README.md new file mode 100644 index 0000000000..dd42d5a789 --- /dev/null +++ b/documentation-website/Writerside/snippets/README.md @@ -0,0 +1,39 @@ +# Exposed Docs code examples + +The `snippets` folder contains a Gradle project with runnable code examples that show how to work with the Exposed library. +Code from these examples is referenced in corresponding documentation sections. + +## Run samples + +Each example has its own `README` file with instructions on how to run it. +To run an example, you can use a **run** Gradle task that depends on an example location. +For example, to run the `exposed-dao` example, open a new terminal window from the `snippets` folder and execute the following command: + +```bash +./gradlew :exposed-dao:run +``` + +Wait until IntelliJ IDEA builds and runs an example. + +## Reference code snippets + +To display a specific source file in a topic, use the `code-block` element with the `src` attribute as follows: + +### XML + +````xml + +```` + +### Markdown + +```` +```kotlin +``` +{src="exposed-dao/src/main/kotlin/org/example/StarWarsFilms.kt"} +```` + +Use the following additional attributes: +- Use the `include-symbol` attribute to display only a specific function from the source file. +- Use the `include-lines` attribute to display specific lines from the source file. + diff --git a/documentation-website/Writerside/snippets/exposed-dao/README.md b/documentation-website/Writerside/snippets/exposed-dao/README.md new file mode 100644 index 0000000000..e1caa36b67 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/README.md @@ -0,0 +1,11 @@ +# Exposed DAO API examples + +A Gradle application that shows how to work with Exposed DAO API. + +## Run + +To run the application, in a terminal window navigate to the `snippets` folder and run the following command: + +```shell +./gradlew :exposed-dao:run +``` diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt index e7e29adf2a..1c4fa88643 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt @@ -1,13 +1,131 @@ package org.example +import org.jetbrains.exposed.dao.id.CompositeID import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction +import java.util.* fun main() { Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") transaction { addLogger(StdOutSqlLogger) - SchemaUtils.create(StarWarsFilms) + createFilms() + createDirectors() + createUsersAndRatings() } } + +fun createFilms() { + SchemaUtils.create(StarWarsFilmsTable) + + //Create a new record + val movie = StarWarsFilmEntity.new { + name = "The Last Jedi" + sequelId = 8 + director = "Rian Johnson" + } + + //Create a new record with id + StarWarsFilmEntity.new(id = 2) { + name = "The Rise of Skywalker" + sequelId = 9 + director = "J.J. Abrams" + } + + //Read a property value + val movieName = movie.name + println("Created a new film named $movieName") + + //Read the id value + val movieId: Int = movie.id.value + println("The id of the new movie is $movieId") + + //Read all movies + val allMovies = StarWarsFilmEntity.all() + allMovies.forEach({ println(it.name)}) + + //Sort results in ascending order + val moviesByAscOrder = StarWarsFilmEntity.all().sortedBy { it.sequelId } + moviesByAscOrder.map { println(it.sequelId) } + + //Sort results in descending order + val moviesByDescOrder = StarWarsFilmEntity.all().sortedByDescending { it.sequelId } + moviesByDescOrder.map { println(it.sequelId) } + + //Read all with a condition + val specificMovie = StarWarsFilmEntity.find { StarWarsFilmsTable.sequelId eq 8 } + specificMovie.forEach({ println("Found a movie with sequelId 8 and name "+it.name)}) + + //Get an entity by its id value + val fifthMovie = StarWarsFilmEntity.findById(2) + println(fifthMovie?.name) + + //Update an entity value + movie.name = "Episode VIII – The Last Jedi" + + //Find by id and update + val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(5) { + it.name = "Episode VIII – The Last Jedi" + } + println(updatedMovie?.name) + + //Find a single record by a condition and update + val updatedMovie2 = StarWarsFilmEntity.findSingleByAndUpdate(StarWarsFilmsTable.name eq "The Last Jedi") { + it.name = "Episode VIII – The Last Jedi" + } + println(updatedMovie2?.name) + + //Delete a record + movie.delete() + +} + +fun createDirectors() { + SchemaUtils.create(DirectorsTable) + + val directorId = CompositeID { + it[DirectorsTable.name] = "J.J. Abrams" + it[DirectorsTable.guildId] = UUID.randomUUID() + } + + DirectorEntity.new(directorId) { + genre = Genre.SCI_FI + } + + //find a single record by composite id + val director = DirectorEntity.findById(directorId) + if (director != null) { + println(director.genre) + } + + //Find directors by composite id + val directors = DirectorEntity.find { DirectorsTable.id eq directorId } + directors.forEach({ println(it.genre)}) +} + +fun createUsersAndRatings() { + SchemaUtils.create(UsersTable) + SchemaUtils.create(UserRatingsTable) + SchemaUtils.create(CitiesTable) + + //Read an entity with a join to another table + val query = UsersTable.innerJoin(UserRatingsTable).innerJoin(StarWarsFilmsTable) + .select(UsersTable.columns) + .where { + StarWarsFilmsTable.sequelId eq 2 and (UserRatingsTable.value greater 5) + }.withDistinct() + + val users = UserEntity.wrapRows(query).toList() + users.map { println(it.name) } + + CitiesTable.insert { + it[name] = "Amsterdam" + } + //Use a query as an expression to sort cities by the number of users in each city + val expression = wrapAsExpression(UsersTable.select(UsersTable.id.count()).where { CitiesTable.id eq UsersTable.cityId }) + val cities = CitiesTable.selectAll().orderBy(expression, SortOrder.DESC).toList() + + cities.map { println(it[CitiesTable.name]) } +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt new file mode 100644 index 0000000000..a776573768 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt @@ -0,0 +1,12 @@ +package org.example + +import org.jetbrains.exposed.dao.CompositeEntity +import org.jetbrains.exposed.dao.CompositeEntityClass +import org.jetbrains.exposed.dao.id.CompositeID +import org.jetbrains.exposed.dao.id.EntityID + +class DirectorEntity(id: EntityID) : CompositeEntity(id) { + companion object : CompositeEntityClass(DirectorsTable) + + var genre by DirectorsTable.genre +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt new file mode 100644 index 0000000000..d80fff68a5 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt @@ -0,0 +1,13 @@ +package org.example + +import org.jetbrains.exposed.dao.IntEntity +import org.jetbrains.exposed.dao.IntEntityClass +import org.jetbrains.exposed.dao.id.EntityID + +class StarWarsFilmEntity(id: EntityID) : IntEntity(id) { + companion object : IntEntityClass(StarWarsFilmsTable) + + var sequelId by StarWarsFilmsTable.sequelId + var name by StarWarsFilmsTable.name + var director by StarWarsFilmsTable.director +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt new file mode 100644 index 0000000000..93d7c442d5 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt @@ -0,0 +1,11 @@ +package org.example + +import org.jetbrains.exposed.dao.IntEntity +import org.jetbrains.exposed.dao.IntEntityClass +import org.jetbrains.exposed.dao.id.EntityID + +class UserEntity(id: EntityID) : IntEntity(id) { + companion object : IntEntityClass(UsersTable) + + var name by UsersTable.name +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt new file mode 100644 index 0000000000..ede2305649 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt @@ -0,0 +1,13 @@ +package org.example + +import org.jetbrains.exposed.dao.IntEntity +import org.jetbrains.exposed.dao.IntEntityClass +import org.jetbrains.exposed.dao.id.EntityID + +class UserRatingEntity(id: EntityID) : IntEntity(id) { + companion object : IntEntityClass(UserRatingsTable) + + var value by UserRatingsTable.value + var film by StarWarsFilmEntity referencedOn UserRatingsTable.film // use referencedOn for normal references + var user by UserEntity referencedOn UserRatingsTable.user +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt new file mode 100644 index 0000000000..a17a255a42 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt @@ -0,0 +1,7 @@ +package org.example + +import org.jetbrains.exposed.dao.id.IntIdTable + +object CitiesTable : IntIdTable() { + val name = varchar("name", 50) +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt new file mode 100644 index 0000000000..740d76406c --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt @@ -0,0 +1,12 @@ +package org.example + +import org.jetbrains.exposed.dao.id.EntityID +import org.jetbrains.exposed.dao.id.IdTable +import org.jetbrains.exposed.sql.Column + +object DirectorsCustomTable : IdTable("directors") { + override val id: Column> = varchar("id", 32).entityId() + val name = varchar("name", 50) + + override val primaryKey = PrimaryKey(id) +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt new file mode 100644 index 0000000000..8bedc80a20 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt @@ -0,0 +1,13 @@ +package org.example + +import org.jetbrains.exposed.dao.id.CompositeIdTable + +enum class Genre { HORROR, DRAMA, THRILLER, SCI_FI } + +object DirectorsTable : CompositeIdTable("directors") { + val name = varchar("name", 50).entityId() + val guildId = uuid("guild_id").autoGenerate().entityId() + val genre = enumeration("genre") + + override val primaryKey = PrimaryKey(name, guildId) +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/StarWarsFilms.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt similarity index 91% rename from documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/StarWarsFilms.kt rename to documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt index f3fcd45232..58d53a7cab 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/StarWarsFilms.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt @@ -11,7 +11,7 @@ SEQUEL_ID INT NOT NULL, "name" VARCHAR(50) NOT NULL, DIRECTOR VARCHAR(50) NOT NULL); */ -object StarWarsFilms : IntIdTable() { +object StarWarsFilmsTable : IntIdTable() { val sequelId = integer("sequel_id").uniqueIndex() val name = varchar("name", MAX_VARCHAR_LENGTH) val director = varchar("director", MAX_VARCHAR_LENGTH) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt new file mode 100644 index 0000000000..94539f1ca2 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt @@ -0,0 +1,9 @@ +package org.example + +import org.jetbrains.exposed.dao.id.IntIdTable + +object UserRatingsTable : IntIdTable() { + val value = long("value") + val film = reference("film", StarWarsFilmsTable) + val user = reference("user", UsersTable) +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt new file mode 100644 index 0000000000..9eb829205e --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt @@ -0,0 +1,8 @@ +package org.example + +import org.jetbrains.exposed.dao.id.IntIdTable + +object UsersTable : IntIdTable() { + val name = varchar("name", 50) + val cityId = reference("cityId", CitiesTable.id) +} From d8f33795a3e86733e40e70d57eb28037609defe6 Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Tue, 1 Oct 2024 14:30:01 +0200 Subject: [PATCH 3/9] replace code blocks with references from code snippets and move the entity definition section --- .../Writerside/topics/DAO-Table-Types.topic | 141 ++++++++---------- 1 file changed, 60 insertions(+), 81 deletions(-) diff --git a/documentation-website/Writerside/topics/DAO-Table-Types.topic b/documentation-website/Writerside/topics/DAO-Table-Types.topic index c97432ca3e..6505b1f125 100644 --- a/documentation-website/Writerside/topics/DAO-Table-Types.topic +++ b/documentation-website/Writerside/topics/DAO-Table-Types.topic @@ -50,7 +50,7 @@

    The following example represents a table with custom columns sequel_id, name, and director:

    - +

    The IntIdTable class automatically generates an auto-incrementing integer id @@ -59,11 +59,57 @@ When the table is created, it corresponds to the following SQL query:

    - +

    For more information on defining and configuring tables in Exposed, see .

    + + +

    + To define multiple columns as part of the primary key and id, use CompositeIdTable and mark each + composite column using entityId(). + Each component column will be available for CRUD operations either individually (as for any standard column) + or all together as part of the id column: +

    + + + + + ("genre") + + init { + addIdColumn(guildId) + } + + override val primaryKey = PrimaryKey(name, guildId) + } + ]]> +
    + + +

    + To define a custom column type as the primary key and id, use a typed IdTable directly and + override the id column: +

    + +

    + In this example, the id field is defined as type Column<EntityID<String>>, + to hold String values with a length of up to 32 characters. Using the + override keyword indicates that this id column is overriding the default + id column provided by IdTable. +

    +

    + Once all columns are defined, the id column is explicitly set as the primary key for the table, + using the override keyword once again. +

    +

    Representing database tables as Kotlin objects ensures type safety and allows you to work with database @@ -75,99 +121,32 @@

    An entity instance is defined as a class. - For example, given the above table definition of StarWarsFilms, + For example, given the above table definition of StarWarsFilmsTable, the corresponding entity class can be defined as follows:

    - ) : IntEntity(id) { - companion object : IntEntityClass(StarWarsFilms) - - var sequelId by StarWarsFilms.sequelId - var name by StarWarsFilms.name - var director by StarWarsFilms.director - } - ]]> +
  • - Since the StarWarsFilms table is an IntIdTable, the StarWarsFilm class extends from IntEntity, - which indicates that the id and primary key of the StarWarsFilm table is of type Int. + Since StarWarsFilmsTable is an IntIdTable, the StarWarsFilmsEntity class extends from IntEntity, + which indicates that the id and primary key of StarWarsFilmsTable is of type Int.
  • The companion object block defines an EntityClass which is responsible for maintaining - the relation between the StarWarsFilm class and the actual table object, StarWarsFilms. + the relation between the StarWarsFilmsEntity class and the actual table object, StarWarsFilmsTable.
  • Each column in the table is represented as a property in the class, where the by keyword ensures the data is fetched or updated from the corresponding column when accessed.
  • -

    +

    Once the entity class is defined, instances of this class allow you to manipulate individual records - from the corresponding table. This could involve - creating a new record, - retrieving a row based on its primary key, - updating values, or - deleting records. -

    - - - -

    To define multiple columns as part of the primary key and id, use CompositeIdTable and mark each composite column using - entityId(). - Each component column will be available for CRUD operations either individually (as for any standard column) or all together as part of the - id column:

    - - ("genre") - - override val primaryKey = PrimaryKey(name, guildId) - } - - class Director(id: EntityID) : CompositeEntity(id) { - companion object : CompositeEntityClass(Directors) - - var genre by Directors.genre - } - ]]> - - - ("genre") - - init { - addIdColumn(guildId) - } - - override val primaryKey = PrimaryKey(name, guildId) - } - ]]> -
    - - -

    To define a custom column type as the primary key and id, use a typed IdTable directly and override the id column:

    - - ("directors") { - override val id: Column> = varchar("id", 32).entityId() - val name = varchar("name", 50) - - override val primaryKey = PrimaryKey(id) - } - - class Director(id: EntityID) : Entity(id) { - companion object : EntityClass(Directors) - - var name by Directors.name - } - ]]> + from the corresponding table. This could involve + creating a new record, + retrieving a row based on its primary key, + updating values, or + deleting records. +

    From 43cebfb4b8740a175f9a43cee0e5385bc6a0c5ef Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Tue, 1 Oct 2024 15:15:06 +0200 Subject: [PATCH 4/9] reference code from snippets in the DAO CRUD operations topic and fix warnings --- .../src/main/kotlin/org/example/App.kt | 63 ++++----- .../org/example/entities/DirectorEntity.kt | 3 +- .../example/entities/StarWarsFilmEntity.kt | 3 +- .../kotlin/org/example/entities/UserEntity.kt | 3 +- .../org/example/entities/UserRatingEntity.kt | 3 +- .../kotlin/org/example/tables/CitiesTable.kt | 2 +- .../example/tables/CustomColumnTypeTable.kt | 2 +- .../org/example/tables/DirectorsTable.kt | 2 +- .../org/example/tables/StarWarsFilmsTable.kt | 2 +- .../org/example/tables/UserRatingsTable.kt | 2 +- .../kotlin/org/example/tables/UsersTable.kt | 2 +- .../topics/DAO-CRUD-Operations.topic | 123 ++++-------------- .../Writerside/topics/DAO-Table-Types.topic | 2 +- 13 files changed, 75 insertions(+), 137 deletions(-) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt index 1c4fa88643..936fbdd430 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt @@ -20,66 +20,65 @@ fun main() { fun createFilms() { SchemaUtils.create(StarWarsFilmsTable) - //Create a new record + // Create a new record val movie = StarWarsFilmEntity.new { name = "The Last Jedi" sequelId = 8 director = "Rian Johnson" } - //Create a new record with id + // Create a new record with id StarWarsFilmEntity.new(id = 2) { name = "The Rise of Skywalker" sequelId = 9 director = "J.J. Abrams" } - //Read a property value + // Read a property value val movieName = movie.name println("Created a new film named $movieName") - //Read the id value + // Read the id value val movieId: Int = movie.id.value println("The id of the new movie is $movieId") - //Read all movies + // Read all movies val allMovies = StarWarsFilmEntity.all() - allMovies.forEach({ println(it.name)}) + allMovies.forEach({ println(it.name) }) - //Sort results in ascending order + // Sort results in ascending order val moviesByAscOrder = StarWarsFilmEntity.all().sortedBy { it.sequelId } moviesByAscOrder.map { println(it.sequelId) } - //Sort results in descending order + // Sort results in descending order val moviesByDescOrder = StarWarsFilmEntity.all().sortedByDescending { it.sequelId } moviesByDescOrder.map { println(it.sequelId) } - //Read all with a condition + // Read all with a condition val specificMovie = StarWarsFilmEntity.find { StarWarsFilmsTable.sequelId eq 8 } - specificMovie.forEach({ println("Found a movie with sequelId 8 and name "+it.name)}) + specificMovie.forEach({ println("Found a movie with sequelId 8 and name " + it.name) }) - //Get an entity by its id value - val fifthMovie = StarWarsFilmEntity.findById(2) + // Get an entity by its id value + val fifthMovie = StarWarsFilmEntity.findById(5) println(fifthMovie?.name) - //Update an entity value + // Update an entity value movie.name = "Episode VIII – The Last Jedi" - //Find by id and update + // Find by id and update val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(5) { it.name = "Episode VIII – The Last Jedi" } println(updatedMovie?.name) - //Find a single record by a condition and update + // Find a single record by a condition and update val updatedMovie2 = StarWarsFilmEntity.findSingleByAndUpdate(StarWarsFilmsTable.name eq "The Last Jedi") { it.name = "Episode VIII – The Last Jedi" } println(updatedMovie2?.name) - //Delete a record + // Delete a record movie.delete() - } fun createDirectors() { @@ -94,15 +93,15 @@ fun createDirectors() { genre = Genre.SCI_FI } - //find a single record by composite id - val director = DirectorEntity.findById(directorId) - if (director != null) { - println(director.genre) - } - - //Find directors by composite id + // Find records by composite id + /* + SELECT DIRECTORS."name", DIRECTORS.GUILD_ID, DIRECTORS.GENRE + FROM DIRECTORS + WHERE (DIRECTORS."name" = 'J.J. Abrams') + AND (DIRECTORS.GUILD_ID = '2cc64f4f-1a2c-41ce-bda1-ee492f787f4b') + */ val directors = DirectorEntity.find { DirectorsTable.id eq directorId } - directors.forEach({ println(it.genre)}) + directors.forEach({ println(it.genre) }) } fun createUsersAndRatings() { @@ -110,7 +109,7 @@ fun createUsersAndRatings() { SchemaUtils.create(UserRatingsTable) SchemaUtils.create(CitiesTable) - //Read an entity with a join to another table + // Read an entity with a join to another table val query = UsersTable.innerJoin(UserRatingsTable).innerJoin(StarWarsFilmsTable) .select(UsersTable.columns) .where { @@ -123,9 +122,15 @@ fun createUsersAndRatings() { CitiesTable.insert { it[name] = "Amsterdam" } - //Use a query as an expression to sort cities by the number of users in each city - val expression = wrapAsExpression(UsersTable.select(UsersTable.id.count()).where { CitiesTable.id eq UsersTable.cityId }) - val cities = CitiesTable.selectAll().orderBy(expression, SortOrder.DESC).toList() + + // Use a query as an expression to sort cities by the number of users in each city + val expression = wrapAsExpression( + UsersTable.select(UsersTable.id.count()) + .where { CitiesTable.id eq UsersTable.cityId } + ) + val cities = CitiesTable.selectAll() + .orderBy(expression, SortOrder.DESC) + .toList() cities.map { println(it[CitiesTable.name]) } } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt index a776573768..4d858a0f9a 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorEntity.kt @@ -1,5 +1,6 @@ -package org.example +package org.example.entities +import org.example.tables.DirectorsTable import org.jetbrains.exposed.dao.CompositeEntity import org.jetbrains.exposed.dao.CompositeEntityClass import org.jetbrains.exposed.dao.id.CompositeID diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt index d80fff68a5..fae6592e43 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsFilmEntity.kt @@ -1,5 +1,6 @@ -package org.example +package org.example.entities +import org.example.tables.StarWarsFilmsTable import org.jetbrains.exposed.dao.IntEntity import org.jetbrains.exposed.dao.IntEntityClass import org.jetbrains.exposed.dao.id.EntityID diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt index 93d7c442d5..c3f7ede64e 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserEntity.kt @@ -1,5 +1,6 @@ -package org.example +package org.example.entities +import org.example.tables.UsersTable import org.jetbrains.exposed.dao.IntEntity import org.jetbrains.exposed.dao.IntEntityClass import org.jetbrains.exposed.dao.id.EntityID diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt index ede2305649..601c68c6b9 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/UserRatingEntity.kt @@ -1,5 +1,6 @@ -package org.example +package org.example.entities +import org.example.tables.UserRatingsTable import org.jetbrains.exposed.dao.IntEntity import org.jetbrains.exposed.dao.IntEntityClass import org.jetbrains.exposed.dao.id.EntityID diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt index a17a255a42..2c177b95ef 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt @@ -1,4 +1,4 @@ -package org.example +package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt index 740d76406c..e398a92a23 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt @@ -1,4 +1,4 @@ -package org.example +package org.example.tables import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IdTable diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt index 8bedc80a20..628c547486 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt @@ -1,4 +1,4 @@ -package org.example +package org.example.tables import org.jetbrains.exposed.dao.id.CompositeIdTable diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt index 58d53a7cab..99f07d68e8 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt @@ -1,4 +1,4 @@ -package org.example +package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt index 94539f1ca2..7d85903e9d 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UserRatingsTable.kt @@ -1,4 +1,4 @@ -package org.example +package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt index 9eb829205e..f40ec8687d 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt @@ -1,4 +1,4 @@ -package org.example +package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable diff --git a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic index 93e01ef9dc..5e99634a6b 100644 --- a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic +++ b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic @@ -18,13 +18,7 @@

    To create a new table row, use the new function on the entity class:

    - - val movie = StarWarsFilm.new { - name = "The Last Jedi" - sequelId = 8 - director = "Rian Johnson" - } - +

    In the above example StarWarsFilm would be the entity instance linked to the StarWarsFilms table. @@ -32,103 +26,64 @@

    To provide a manual id value to a new entity, pass the value as an argument to the id parameter:

    - - StarWarsFilm.new(id = 2) { - name = "The Rise of Skywalker" - sequelId = 9 - director = "J.J. Abrams" - } - +

    If the entity is a CompositeEntity, the id value can be constructed by creating a component column-to-value association using CompositeID:

    - - val newId = CompositeID { - it[Directors.name] = "J.J. Abrams" - it[Directors.guildId] = UUID.randomUUID() - } - - Director.new(newId) { - genre = Genre.SCI_FI - } - +

    To read a value from a property, simply access it as you would with any property in a Kotlin class:

    - - val name = movie.name - + An entity's id property is wrapped as an instance of the EntityID class. To access the actual wrapped value, for example the stored Int from a StarWarsFilm entity, use EntityID.value: - - val id: Int = movie.id.value - +

    To retrieve entities, use one of the following methods:

    To get all the entity instances associated with this entity class, use the all() function: - - val movies = StarWarsFilm.all() - + To get all the entity instances that conform to the conditional expression, use the find() function: - - val movies = StarWarsFilm.find { StarWarsFilms.sequelId eq 8 } - + To get an entity by its id value, use the findById() function: - - val movie = StarWarsFilm.findById(5) - + - - For a list of available predicates, see - DSL Where expression. -

    If the entity is a CompositeEntity, its id property can be used to refer to all composite columns and to get entities, much like the id column of its associated CompositeIdTable:

    - - - val directorId = CompositeID { - it[Directors.name] = "George Lucas" - it[Directors.guildId] = "..." - } - - // these will both deconstruct in SQL to the 2 component columns - val director = Director.findById(directorId) - val directors = Director.find { Directors.id eq directorId } - + +

    + The SQL query would result in something like the following: +

    + + + For a list of available predicates, see + DSL Where expression. +

    Suppose that you want to find all users who rated the second Star Wars film with a score greater than 5. First, you would write that query using Exposed DSL.

    - - val query = Users.innerJoin(UserRatings).innerJoin(StarWarsFilm) - .select(Users.columns) - .where { - StarWarsFilms.sequelId eq 2 and (UserRatings.value gt 5) - }.withDistinct() - +

    Once the query is defined, you can wrap the result in the User entity using the wrapRows() function to generate entities from the retrieved data:

    - - val users = User.wrapRows(query).toList() - +

    @@ -136,15 +91,11 @@

    To sort results in ascending order, use sortedBy:

    - - val movies = StarWarsFilm.all().sortedBy { it.sequelId } - +

    To sort results in descending order, use sortedByDescending:

    - - val movies = StarWarsFilm.all().sortedByDescending { it.sequelId } - +
    @@ -152,9 +103,7 @@

    You can update the value of a property just as you would with any property in a Kotlin class:

    - - movie.name = "Episode VIII – The Last Jedi" - + Exposed doesn't make an immediate update when you set a new value for Entity, it just stores it on the inner map. "Flushing" values to the database occurs at the end of the transaction, or before the next SELECT * from the database. @@ -163,22 +112,14 @@

    To search for an entity by its id and apply an update, use the findByIdAndUpdate() function:

    - - val updatedMovie = StarWarsFilm.findByIdAndUpdate(5) { - it.name = "Episode VIII – The Last Jedi" - } - +

    To search for a single entity by a query and apply an update, use the findSingleByAndUpdate() function:

    - - val updatedMovie2 = StarWarsFilm.findSingleByAndUpdate(StarWarsFilms.name eq "The Last Jedi") { - it.name = "Episode VIII – The Last Jedi" - } - +
    @@ -186,9 +127,7 @@

    To delete a record, use the delete() function:

    - - movie.delete() - + @@ -197,17 +136,7 @@ then order the result by that count.To do so, however, you need to convert the Query to an Expression. This can be done using the wrapAsExpression() function:

    - - val expression = wrapAsExpression<Int>(Users - .select(Users.id.count()) - .where { - Cities.id eq Users.cityId - }) - val cities = Cities - .selectAll() - .orderBy(expression, SortOrder.DESC) - .toList() - +
    diff --git a/documentation-website/Writerside/topics/DAO-Table-Types.topic b/documentation-website/Writerside/topics/DAO-Table-Types.topic index 6505b1f125..77e77f928f 100644 --- a/documentation-website/Writerside/topics/DAO-Table-Types.topic +++ b/documentation-website/Writerside/topics/DAO-Table-Types.topic @@ -124,7 +124,7 @@ For example, given the above table definition of StarWarsFilmsTable, the corresponding entity class can be defined as follows:

    - +
  • Since StarWarsFilmsTable is an IntIdTable, the StarWarsFilmsEntity class extends from IntEntity, From 279329f096677d619eaf5e07d7fa1489de31ffdd Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Tue, 1 Oct 2024 15:51:08 +0200 Subject: [PATCH 5/9] add missing imports --- .../src/main/kotlin/org/example/App.kt | 2 + .../topics/DAO-CRUD-Operations.topic | 38 +++++++++---------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt index 936fbdd430..0f9cc3aab7 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt @@ -1,5 +1,7 @@ package org.example +import org.example.entities.* +import org.example.tables.* import org.jetbrains.exposed.dao.id.CompositeID import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq diff --git a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic index 5e99634a6b..dee89035e5 100644 --- a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic +++ b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic @@ -18,7 +18,7 @@

    To create a new table row, use the new function on the entity class:

    - +

    In the above example StarWarsFilm would be the entity instance linked to the StarWarsFilms table. @@ -26,51 +26,51 @@

    To provide a manual id value to a new entity, pass the value as an argument to the id parameter:

    - +

    If the entity is a CompositeEntity, the id value can be constructed by creating a component column-to-value association using CompositeID:

    - +

    To read a value from a property, simply access it as you would with any property in a Kotlin class:

    - + An entity's id property is wrapped as an instance of the EntityID class. To access the actual wrapped value, for example the stored Int from a StarWarsFilm entity, use EntityID.value: - +

    To retrieve entities, use one of the following methods:

    To get all the entity instances associated with this entity class, use the all() function: - + To get all the entity instances that conform to the conditional expression, use the find() function: - + To get an entity by its id value, use the findById() function: - +

    If the entity is a CompositeEntity, its id property can be used to refer to all composite columns and to get entities, much like the id column of its associated CompositeIdTable:

    - +

    The SQL query would result in something like the following:

    - + For a list of available predicates, see DSL Where expression. @@ -79,11 +79,11 @@

    Suppose that you want to find all users who rated the second Star Wars film with a score greater than 5. First, you would write that query using Exposed DSL.

    - +

    Once the query is defined, you can wrap the result in the User entity using the wrapRows() function to generate entities from the retrieved data:

    - +

    @@ -91,11 +91,11 @@

    To sort results in ascending order, use sortedBy:

    - +

    To sort results in descending order, use sortedByDescending:

    - +
    @@ -103,7 +103,7 @@

    You can update the value of a property just as you would with any property in a Kotlin class:

    - + Exposed doesn't make an immediate update when you set a new value for Entity, it just stores it on the inner map. "Flushing" values to the database occurs at the end of the transaction, or before the next SELECT * from the database. @@ -112,14 +112,14 @@

    To search for an entity by its id and apply an update, use the findByIdAndUpdate() function:

    - +

    To search for a single entity by a query and apply an update, use the findSingleByAndUpdate() function:

    - +
    @@ -127,7 +127,7 @@

    To delete a record, use the delete() function:

    - + @@ -136,7 +136,7 @@ then order the result by that count.To do so, however, you need to convert the Query to an Expression. This can be done using the wrapAsExpression() function:

    - +
    From f63fc6390169120cdf39ca994aa2933fdb425a3d Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Wed, 2 Oct 2024 16:38:46 +0200 Subject: [PATCH 6/9] address comments and reorganize code examples --- documentation-website/Writerside/hi.tree | 1 + .../src/main/kotlin/org/example/App.kt | 146 +++--------------- .../example/entities/ComputedFieldEntity.kt | 25 +++ .../entities/CustomColumnTypeEntity.kt | 12 ++ .../org/example/examples/CreateExamples.kt | 37 +++++ .../org/example/examples/DeleteExamples.kt | 14 ++ .../org/example/examples/ReadExamples.kt | 105 +++++++++++++ .../org/example/examples/UpdateExamples.kt | 22 +++ .../org/example/tables/ComputedFieldTable.kt | 13 ++ .../example/tables/CustomColumnTypeTable.kt | 2 +- .../tables/DirectorsWithGuildRefTable.kt | 15 ++ .../kotlin/org/example/tables/GuildsTable.kt | 5 + .../topics/DAO-CRUD-Operations.topic | 108 +++++-------- .../topics/DAO-Entity-definition.topic | 50 ++++++ .../Writerside/topics/DAO-Table-Types.topic | 93 ++++------- 15 files changed, 395 insertions(+), 253 deletions(-) create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/ComputedFieldEntity.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/CustomColumnTypeEntity.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/ComputedFieldTable.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt create mode 100644 documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/GuildsTable.kt create mode 100644 documentation-website/Writerside/topics/DAO-Entity-definition.topic diff --git a/documentation-website/Writerside/hi.tree b/documentation-website/Writerside/hi.tree index 2a984611fa..2529375ba8 100644 --- a/documentation-website/Writerside/hi.tree +++ b/documentation-website/Writerside/hi.tree @@ -29,6 +29,7 @@ + diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt index 0f9cc3aab7..a56a9583f1 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt @@ -1,138 +1,34 @@ package org.example -import org.example.entities.* -import org.example.tables.* -import org.jetbrains.exposed.dao.id.CompositeID -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.example.examples.* +import org.example.tables.CitiesTable +import org.example.tables.DirectorsTable +import org.example.tables.StarWarsFilmsTable +import org.example.tables.UserRatingsTable +import org.example.tables.UsersTable +import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.SchemaUtils +import org.jetbrains.exposed.sql.StdOutSqlLogger +import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.transactions.transaction -import java.util.* fun main() { Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") transaction { addLogger(StdOutSqlLogger) - createFilms() - createDirectors() - createUsersAndRatings() - } -} - -fun createFilms() { - SchemaUtils.create(StarWarsFilmsTable) - - // Create a new record - val movie = StarWarsFilmEntity.new { - name = "The Last Jedi" - sequelId = 8 - director = "Rian Johnson" - } - - // Create a new record with id - StarWarsFilmEntity.new(id = 2) { - name = "The Rise of Skywalker" - sequelId = 9 - director = "J.J. Abrams" - } - - // Read a property value - val movieName = movie.name - println("Created a new film named $movieName") - - // Read the id value - val movieId: Int = movie.id.value - println("The id of the new movie is $movieId") - - // Read all movies - val allMovies = StarWarsFilmEntity.all() - allMovies.forEach({ println(it.name) }) - - // Sort results in ascending order - val moviesByAscOrder = StarWarsFilmEntity.all().sortedBy { it.sequelId } - moviesByAscOrder.map { println(it.sequelId) } - - // Sort results in descending order - val moviesByDescOrder = StarWarsFilmEntity.all().sortedByDescending { it.sequelId } - moviesByDescOrder.map { println(it.sequelId) } - - // Read all with a condition - val specificMovie = StarWarsFilmEntity.find { StarWarsFilmsTable.sequelId eq 8 } - specificMovie.forEach({ println("Found a movie with sequelId 8 and name " + it.name) }) - - // Get an entity by its id value - val fifthMovie = StarWarsFilmEntity.findById(5) - println(fifthMovie?.name) - - // Update an entity value - movie.name = "Episode VIII – The Last Jedi" - - // Find by id and update - val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(5) { - it.name = "Episode VIII – The Last Jedi" - } - println(updatedMovie?.name) - - // Find a single record by a condition and update - val updatedMovie2 = StarWarsFilmEntity.findSingleByAndUpdate(StarWarsFilmsTable.name eq "The Last Jedi") { - it.name = "Episode VIII – The Last Jedi" - } - println(updatedMovie2?.name) - - // Delete a record - movie.delete() -} - -fun createDirectors() { - SchemaUtils.create(DirectorsTable) - - val directorId = CompositeID { - it[DirectorsTable.name] = "J.J. Abrams" - it[DirectorsTable.guildId] = UUID.randomUUID() - } + SchemaUtils.create(StarWarsFilmsTable) + SchemaUtils.create(DirectorsTable) + SchemaUtils.create(UsersTable) + SchemaUtils.create(UserRatingsTable) + SchemaUtils.create(CitiesTable) - DirectorEntity.new(directorId) { - genre = Genre.SCI_FI - } - - // Find records by composite id - /* - SELECT DIRECTORS."name", DIRECTORS.GUILD_ID, DIRECTORS.GENRE - FROM DIRECTORS - WHERE (DIRECTORS."name" = 'J.J. Abrams') - AND (DIRECTORS.GUILD_ID = '2cc64f4f-1a2c-41ce-bda1-ee492f787f4b') - */ - val directors = DirectorEntity.find { DirectorsTable.id eq directorId } - directors.forEach({ println(it.genre) }) -} - -fun createUsersAndRatings() { - SchemaUtils.create(UsersTable) - SchemaUtils.create(UserRatingsTable) - SchemaUtils.create(CitiesTable) + // Create examples + val createExamples = CreateExamples() + createExamples.createFilms() - // Read an entity with a join to another table - val query = UsersTable.innerJoin(UserRatingsTable).innerJoin(StarWarsFilmsTable) - .select(UsersTable.columns) - .where { - StarWarsFilmsTable.sequelId eq 2 and (UserRatingsTable.value greater 5) - }.withDistinct() - - val users = UserEntity.wrapRows(query).toList() - users.map { println(it.name) } - - CitiesTable.insert { - it[name] = "Amsterdam" + // Read examples + val readExamples = ReadExamples() + readExamples.readExamples() } - - // Use a query as an expression to sort cities by the number of users in each city - val expression = wrapAsExpression( - UsersTable.select(UsersTable.id.count()) - .where { CitiesTable.id eq UsersTable.cityId } - ) - val cities = CitiesTable.selectAll() - .orderBy(expression, SortOrder.DESC) - .toList() - - cities.map { println(it[CitiesTable.name]) } } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/ComputedFieldEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/ComputedFieldEntity.kt new file mode 100644 index 0000000000..ac927cf514 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/ComputedFieldEntity.kt @@ -0,0 +1,25 @@ +package org.example.entities + +import org.example.tables.StarWarsWFilmsWithRankTable +import org.jetbrains.exposed.dao.IntEntity +import org.jetbrains.exposed.dao.IntEntityClass +import org.jetbrains.exposed.dao.id.EntityID +import org.jetbrains.exposed.sql.Op +import org.jetbrains.exposed.sql.Query + +class StarWarsWFilmWithRankEntity(id: EntityID) : IntEntity(id) { + var sequelId by StarWarsWFilmsWithRankTable.sequelId + var name by StarWarsWFilmsWithRankTable.name + var rating by StarWarsWFilmsWithRankTable.rating + + val rank: Long + get() = readValues[StarWarsWFilmsWithRankTable.rank] + + companion object : IntEntityClass(StarWarsWFilmsWithRankTable) { + override fun searchQuery(op: Op): Query { + return super.searchQuery(op).adjustSelect { + select(columns + StarWarsWFilmsWithRankTable.rank) + } + } + } +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/CustomColumnTypeEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/CustomColumnTypeEntity.kt new file mode 100644 index 0000000000..2070503d6a --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/CustomColumnTypeEntity.kt @@ -0,0 +1,12 @@ +package org.example.entities + +import org.example.tables.DirectorsCustomTable +import org.jetbrains.exposed.dao.Entity +import org.jetbrains.exposed.dao.EntityClass +import org.jetbrains.exposed.dao.id.EntityID + +class DirectorCustomEntity(id: EntityID) : Entity(id) { + companion object : EntityClass(DirectorsCustomTable) + + var name by DirectorsCustomTable.name +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt new file mode 100644 index 0000000000..6c0e13396a --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt @@ -0,0 +1,37 @@ +package org.example.examples + +import org.example.entities.DirectorEntity +import org.example.entities.StarWarsFilmEntity +import org.example.tables.DirectorsTable +import org.example.tables.Genre +import org.jetbrains.exposed.dao.id.CompositeID +import java.util.* + +class CreateExamples { + fun createFilms() { + val movie = StarWarsFilmEntity.new { + name = "The Last Jedi" + sequelId = 8 + director = "Rian Johnson" + } + + // Create a new record with id + val movie2 = StarWarsFilmEntity.new(id = 2) { + name = "The Rise of Skywalker" + sequelId = 9 + director = "J.J. Abrams" + } + } + + fun createNewWithCompositeId() { + val directorId = CompositeID { + it[DirectorsTable.name] = "J.J. Abrams" + it[DirectorsTable.guildId] = UUID.randomUUID() + } + + val director = DirectorEntity.new(directorId) { + genre = Genre.SCI_FI + } + } + +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt new file mode 100644 index 0000000000..90a39b424d --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt @@ -0,0 +1,14 @@ +package org.example.examples + +import org.example.entities.StarWarsFilmEntity + +class DeleteExamples { + fun deleteFilm() { + val movie = StarWarsFilmEntity.new { + name = "The Last Jedi" + sequelId = 8 + director = "Rian Johnson" + } + val deletedMovie = movie.delete() + } +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt new file mode 100644 index 0000000000..7718d73c4c --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt @@ -0,0 +1,105 @@ +package org.example.examples + +import org.example.entities.DirectorEntity +import org.example.entities.StarWarsFilmEntity +import org.example.entities.StarWarsWFilmWithRankEntity +import org.example.entities.UserEntity +import org.example.tables.CitiesTable +import org.example.tables.DirectorsTable +import org.example.tables.StarWarsFilmsTable +import org.example.tables.UserRatingsTable +import org.example.tables.UsersTable +import org.jetbrains.exposed.dao.id.CompositeID +import org.jetbrains.exposed.sql.SortOrder +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.count +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.wrapAsExpression +import java.util.* + +class ReadExamples { + fun readAll() { + // Read all movies + val allMovies = StarWarsFilmEntity.all() + allMovies.forEach({ println(it.name) }) + + // Sort results in ascending order + val moviesByAscOrder = StarWarsFilmEntity.all().sortedBy { it.sequelId } + moviesByAscOrder.map { println(it.sequelId) } + + // Sort results in descending order + val moviesByDescOrder = StarWarsFilmEntity.all().sortedByDescending { it.sequelId } + moviesByDescOrder.map { println(it.sequelId) } + } + + fun find() { + // Get an entity by its id value + val movie = StarWarsFilmEntity.findById(2) + + if(movie != null) { + // Read a property value + val movieName = movie.name + println("Created a new film named $movieName") + + // Read the id value + val movieId: Int = movie.id.value + println("The id of the new movie is $movieId") + } + + // Read all with a condition + val specificMovie = StarWarsFilmEntity.find { StarWarsFilmsTable.sequelId eq 8 } + specificMovie.forEach({ println("Found a movie with sequelId 8 and name " + it.name) }) + } + + // Read an entity with a join to another table + fun readWithJoin() { + val query = UsersTable.innerJoin(UserRatingsTable).innerJoin(StarWarsFilmsTable) + .select(UsersTable.columns) + .where { + StarWarsFilmsTable.sequelId eq 2 and (UserRatingsTable.value greater 5) + }.withDistinct() + + val users = UserEntity.wrapRows(query).toList() + users.map { println(it.name) } + } + + fun findByCompositeId() { + // Find records by composite id + val directorId = CompositeID { + it[DirectorsTable.name] = "J.J. Abrams" + it[DirectorsTable.guildId] = UUID.randomUUID() + } + + val directors = DirectorEntity.find { DirectorsTable.id eq directorId } + directors.forEach({ println(it.genre) }) + } + + fun queriesAsExpressions() { + // Use a query as an expression to sort cities by the number of users in each city + CitiesTable.insert { + it[name] = "Amsterdam" + } + + val expression = wrapAsExpression( + UsersTable.select(UsersTable.id.count()) + .where { CitiesTable.id eq UsersTable.cityId } + ) + val cities = CitiesTable.selectAll() + .orderBy(expression, SortOrder.DESC) + .toList() + + cities.map { println(it[CitiesTable.name]) } + } + + fun readComputedField() { + StarWarsWFilmWithRankEntity.new { + sequelId = 8 + name = "The Last Jedi" + rating = 4.2 + } + + StarWarsWFilmWithRankEntity.find { StarWarsFilmsTable.name like "The%" }.map { it.name to it.rank } + } + +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt new file mode 100644 index 0000000000..ccccc01e00 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt @@ -0,0 +1,22 @@ +package org.example.examples + +import org.example.entities.StarWarsFilmEntity +import org.example.tables.StarWarsFilmsTable +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq + +class UpdateExamples { + fun updateFilms() { + // Find by id and update + val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(5) { + it.name = "Episode VIII – The Last Jedi" + } + println(updatedMovie?.name) + + // Find a single record by a condition and update + val updatedMovie2 = StarWarsFilmEntity.findSingleByAndUpdate(StarWarsFilmsTable.name eq "The Last Jedi") { + it.name = "Episode VIII – The Last Jedi" + } + println(updatedMovie2?.name) + } + +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/ComputedFieldTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/ComputedFieldTable.kt new file mode 100644 index 0000000000..1723f3eb59 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/ComputedFieldTable.kt @@ -0,0 +1,13 @@ +package org.example.tables + +import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.sql.Rank +import org.jetbrains.exposed.sql.SortOrder + +object StarWarsWFilmsWithRankTable : IntIdTable() { + val sequelId = integer("sequel_id").uniqueIndex() + val name = varchar("name", 50) + val rating = double("rating") + + val rank = Rank().over().orderBy(rating, SortOrder.DESC) +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt index e398a92a23..c83cf58bca 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt @@ -4,7 +4,7 @@ import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IdTable import org.jetbrains.exposed.sql.Column -object DirectorsCustomTable : IdTable("directors") { +object DirectorsCustomTable : IdTable() { override val id: Column> = varchar("id", 32).entityId() val name = varchar("name", 50) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt new file mode 100644 index 0000000000..1a4f4c3904 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt @@ -0,0 +1,15 @@ +package org.example.tables + +import org.jetbrains.exposed.dao.id.CompositeIdTable + +object DirectorsWithGuildRefTable : CompositeIdTable() { + val name = varchar("name", 50).entityId() + val guildId = reference("guild_id", GuildsTable) + val genre = enumeration("genre") + + init { + addIdColumn(guildId) + } + + override val primaryKey = PrimaryKey(name, guildId) +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/GuildsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/GuildsTable.kt new file mode 100644 index 0000000000..7d946c6181 --- /dev/null +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/GuildsTable.kt @@ -0,0 +1,5 @@ +package org.example.tables + +import org.jetbrains.exposed.dao.id.UUIDTable + +object GuildsTable : UUIDTable("guilds") diff --git a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic index dee89035e5..21f42be61b 100644 --- a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic +++ b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic @@ -3,7 +3,7 @@ SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd"> + title="CRUD operations" id="DAO-CRUD-Operations">

    @@ -12,65 +12,70 @@

    These operations can be performed directly through the methods and properties of the Entity class - associated with the table. For more information, see . + associated with the table. For more information, see .

    To create a new table row, use the new function on the entity class:

    - +

    - In the above example StarWarsFilm would be the entity instance linked to - the StarWarsFilms table. + In the above example StarWarsFilmEntity would be the entity instance linked to + the StarWarsFilmsTable table.

    To provide a manual id value to a new entity, pass the value as an argument to the id parameter:

    - +

    If the entity is a CompositeEntity, the id value can be constructed by creating a component column-to-value association using CompositeID:

    - +

    To read a value from a property, simply access it as you would with any property in a Kotlin class:

    - + An entity's id property is wrapped as an instance of the EntityID class. To access the actual wrapped value, for example the stored Int from a StarWarsFilm entity, use EntityID.value: - +

    To retrieve entities, use one of the following methods:

    To get all the entity instances associated with this entity class, use the all() function: - + To get all the entity instances that conform to the conditional expression, use the find() function: - + To get an entity by its id value, use the findById() function: - +

    If the entity is a CompositeEntity, its id property can be used to refer to all composite columns and to get entities, much like the id column of its associated CompositeIdTable:

    - +

    The SQL query would result in something like the following:

    - + For a list of available predicates, see DSL Where expression. @@ -79,23 +84,20 @@

    Suppose that you want to find all users who rated the second Star Wars film with a score greater than 5. First, you would write that query using Exposed DSL.

    - +

    Once the query is defined, you can wrap the result in the User entity using the wrapRows() function to generate entities from the retrieved data:

    - +
    -

    - -

    To sort results in ascending order, use sortedBy:

    - +

    To sort results in descending order, use sortedByDescending:

    - +
    @@ -103,7 +105,9 @@

    You can update the value of a property just as you would with any property in a Kotlin class:

    - + + movie.name = "Episode VIII – The Last Jedi" + Exposed doesn't make an immediate update when you set a new value for Entity, it just stores it on the inner map. "Flushing" values to the database occurs at the end of the transaction, or before the next SELECT * from the database. @@ -112,14 +116,14 @@

    To search for an entity by its id and apply an update, use the findByIdAndUpdate() function:

    - +

    To search for a single entity by a query and apply an update, use the findSingleByAndUpdate() function:

    - +
    @@ -127,7 +131,7 @@

    To delete a record, use the delete() function:

    - + @@ -136,7 +140,7 @@ then order the result by that count.To do so, however, you need to convert the Query to an Expression. This can be done using the wrapAsExpression() function:

    - +
    @@ -144,46 +148,18 @@ the entity class can override any open function in EntityClass. However, to achieve this functionality, you only need to override searchQuery(). The results of the function can then be accessed through a property of the entity class:

    - - ) : IntEntity(id) { - var sequelId by StarWarsFilms.sequelId - var name by StarWarsFilms.name - var rating by StarWarsFilms.rating - - val rank: Long - get() = readValues[StarWarsFilms.rank] - - companion object : IntEntityClass(StarWarsFilms) { - override fun searchQuery(op: Op): Query { - return super.searchQuery(op).adjustSelect { - select(columns + StarWarsFilms.rank).set - } - } - } - } - - transaction { - StarWarsFilm.new { - sequelId = 8 - name = "The Last Jedi" - rating = 4.2 - } - // more insertions ... - entityCache.clear() - - // fetch entities with value (or store entities then read value) - StarWarsFilm.find { StarWarsFilms.name like "The%" }.map { it.name to it.rank } - } - ]]> + + + + + + + + +

    + Then, creating and fetching entities would look like this: +

    +
    diff --git a/documentation-website/Writerside/topics/DAO-Entity-definition.topic b/documentation-website/Writerside/topics/DAO-Entity-definition.topic new file mode 100644 index 0000000000..a73c8bc491 --- /dev/null +++ b/documentation-website/Writerside/topics/DAO-Entity-definition.topic @@ -0,0 +1,50 @@ + + + + +

    + Representing database tables as Kotlin objects ensures type safety and allows you to work with database + records just like regular Kotlin objects, taking full advantage of Kotlin's language features. +

    +

    + When using the DAO approach, IdTable needs to be associated with an Entity, because every database record + in this table needs to be mapped to an Entity instance, identified by its primary key. +

    +

    + An entity instance is defined as a class. + In the following example, StarWarsFilmEntity is the entity class linked to the table StarWarsFilmsTable: +

    + + + + + + + + + +
  • + Since StarWarsFilmsTable is an IntIdTable, the StarWarsFilmsEntity class extends from IntEntity, + which indicates that the id and primary key of StarWarsFilmsTable is of type Int. +
  • +
  • + The companion object block defines an EntityClass which is responsible for maintaining + the relation between the StarWarsFilmsEntity class and the actual table object, StarWarsFilmsTable. +
  • +
  • + Each column in the table is represented as a property in the class, where the by keyword + ensures the data is fetched or updated from the corresponding column when accessed. +
  • +
    +

    + Once the entity class is defined, instances of this class allow you to manipulate individual records + from the corresponding table. This could involve + creating a new record, + retrieving a row based on its primary key, + updating values, or + deleting records. +

    + diff --git a/documentation-website/Writerside/topics/DAO-Table-Types.topic b/documentation-website/Writerside/topics/DAO-Table-Types.topic index 77e77f928f..7aeb97363c 100644 --- a/documentation-website/Writerside/topics/DAO-Table-Types.topic +++ b/documentation-website/Writerside/topics/DAO-Table-Types.topic @@ -6,7 +6,8 @@ title="Table types" id="DAO-Table-Types" help-id="DAO-Table-types"> - + + Auto-incrementing <code>id</code> column tables

    Apart from the core Table class, Exposed provides the base @@ -67,41 +68,49 @@

    - To define multiple columns as part of the primary key and id, use CompositeIdTable and mark each - composite column using entityId(). + To define multiple columns as part of the primary key and id, use + CompositeIdTable + and mark each composite column using entityId(). Each component column will be available for CRUD operations either individually (as for any standard column) or all together as part of the id column:

    - + + + + + + + + - ("genre") - - init { - addIdColumn(guildId) - } - - override val primaryKey = PrimaryKey(name, guildId) - } - ]]> + + + + + + + +

    To define a custom column type as the primary key and id, use a typed IdTable directly and - override the id column: + override the id column, as shown in the following example:

    - + + + + + + + +

    - In this example, the id field is defined as type Column<EntityID<String>>, - to hold String values with a length of up to 32 characters. Using the + In the definition of DirectorsCustomTable, the id field is of type Column<EntityID<String>>, + which will hold String values with a length of up to 32 characters. Using the override keyword indicates that this id column is overriding the default id column provided by IdTable.

    @@ -110,44 +119,6 @@ using the override keyword once again.

    - -

    - Representing database tables as Kotlin objects ensures type safety and allows you to work with database - records just like regular Kotlin objects, taking full advantage of Kotlin's language features. -

    -

    - Any IdTable needs to be associated with an Entity, because every database record - in this table needs to be mapped to an Entity instance, identified by its primary key. -

    -

    - An entity instance is defined as a class. - For example, given the above table definition of StarWarsFilmsTable, - the corresponding entity class can be defined as follows: -

    - - -
  • - Since StarWarsFilmsTable is an IntIdTable, the StarWarsFilmsEntity class extends from IntEntity, - which indicates that the id and primary key of StarWarsFilmsTable is of type Int. -
  • -
  • - The companion object block defines an EntityClass which is responsible for maintaining - the relation between the StarWarsFilmsEntity class and the actual table object, StarWarsFilmsTable. -
  • -
  • - Each column in the table is represented as a property in the class, where the by keyword - ensures the data is fetched or updated from the corresponding column when accessed. -
  • -
    -

    - Once the entity class is defined, instances of this class allow you to manipulate individual records - from the corresponding table. This could involve - creating a new record, - retrieving a row based on its primary key, - updating values, or - deleting records. -

    -
    From 15b663c072a61fc186087f57416e50ee3f1c1b24 Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Wed, 2 Oct 2024 17:32:32 +0200 Subject: [PATCH 7/9] fix detekt issues --- ...olumnTypeEntity.kt => DirectorCustomEntity.kt} | 0 ...ldEntity.kt => StarWarsWFilmWithRankEntity.kt} | 0 .../kotlin/org/example/examples/CreateExamples.kt | 10 +++++++--- .../kotlin/org/example/examples/DeleteExamples.kt | 5 ++++- .../kotlin/org/example/examples/ReadExamples.kt | 15 +++++++++------ .../kotlin/org/example/examples/UpdateExamples.kt | 9 +++++++-- .../main/kotlin/org/example/tables/CitiesTable.kt | 4 +++- ...ColumnTypeTable.kt => DirectorsCustomTable.kt} | 7 +++++-- .../kotlin/org/example/tables/DirectorsTable.kt | 3 ++- .../example/tables/DirectorsWithGuildRefTable.kt | 4 +++- ...eldTable.kt => StarWarsWFilmsWithRankTable.kt} | 4 +++- .../main/kotlin/org/example/tables/UsersTable.kt | 4 +++- .../Writerside/topics/DAO-CRUD-Operations.topic | 10 ++++------ .../Writerside/topics/DAO-Table-Types.topic | 4 ++-- 14 files changed, 52 insertions(+), 27 deletions(-) rename documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/{CustomColumnTypeEntity.kt => DirectorCustomEntity.kt} (100%) rename documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/{ComputedFieldEntity.kt => StarWarsWFilmWithRankEntity.kt} (100%) rename documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/{CustomColumnTypeTable.kt => DirectorsCustomTable.kt} (55%) rename documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/{ComputedFieldTable.kt => StarWarsWFilmsWithRankTable.kt} (80%) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/CustomColumnTypeEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorCustomEntity.kt similarity index 100% rename from documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/CustomColumnTypeEntity.kt rename to documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/DirectorCustomEntity.kt diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/ComputedFieldEntity.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsWFilmWithRankEntity.kt similarity index 100% rename from documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/ComputedFieldEntity.kt rename to documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/entities/StarWarsWFilmWithRankEntity.kt diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt index 6c0e13396a..1401e1f876 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt @@ -7,20 +7,25 @@ import org.example.tables.Genre import org.jetbrains.exposed.dao.id.CompositeID import java.util.* +const val MOVIE_SEQUELID = 8 +const val MOVIE2_SEQUELID = 9 + class CreateExamples { fun createFilms() { val movie = StarWarsFilmEntity.new { name = "The Last Jedi" - sequelId = 8 + sequelId = MOVIE_SEQUELID director = "Rian Johnson" } + println(movie) // Create a new record with id val movie2 = StarWarsFilmEntity.new(id = 2) { name = "The Rise of Skywalker" - sequelId = 9 + sequelId = MOVIE2_SEQUELID director = "J.J. Abrams" } + println(movie2) } fun createNewWithCompositeId() { @@ -33,5 +38,4 @@ class CreateExamples { genre = Genre.SCI_FI } } - } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt index 90a39b424d..8c44384644 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt @@ -2,13 +2,16 @@ package org.example.examples import org.example.entities.StarWarsFilmEntity +const val SEQUEL_ID = 8 + class DeleteExamples { fun deleteFilm() { val movie = StarWarsFilmEntity.new { name = "The Last Jedi" - sequelId = 8 + sequelId = SEQUEL_ID director = "Rian Johnson" } val deletedMovie = movie.delete() + println(deletedMovie) } } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt index 7718d73c4c..0358edeeae 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt @@ -18,6 +18,10 @@ import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.wrapAsExpression import java.util.* +const val MOVIE_SEQUELID = 8 +const val MIN_MOVIE_RATING = 5 +const val MOVIE_RATING = 4.2 + class ReadExamples { fun readAll() { // Read all movies @@ -37,7 +41,7 @@ class ReadExamples { // Get an entity by its id value val movie = StarWarsFilmEntity.findById(2) - if(movie != null) { + if (movie != null) { // Read a property value val movieName = movie.name println("Created a new film named $movieName") @@ -48,7 +52,7 @@ class ReadExamples { } // Read all with a condition - val specificMovie = StarWarsFilmEntity.find { StarWarsFilmsTable.sequelId eq 8 } + val specificMovie = StarWarsFilmEntity.find { StarWarsFilmsTable.sequelId eq MOVIE_SEQUELID } specificMovie.forEach({ println("Found a movie with sequelId 8 and name " + it.name) }) } @@ -57,7 +61,7 @@ class ReadExamples { val query = UsersTable.innerJoin(UserRatingsTable).innerJoin(StarWarsFilmsTable) .select(UsersTable.columns) .where { - StarWarsFilmsTable.sequelId eq 2 and (UserRatingsTable.value greater 5) + StarWarsFilmsTable.sequelId eq MOVIE_SEQUELID and (UserRatingsTable.value greater MIN_MOVIE_RATING) }.withDistinct() val users = UserEntity.wrapRows(query).toList() @@ -94,12 +98,11 @@ class ReadExamples { fun readComputedField() { StarWarsWFilmWithRankEntity.new { - sequelId = 8 + sequelId = MOVIE_SEQUELID name = "The Last Jedi" - rating = 4.2 + rating = MOVIE_RATING } StarWarsWFilmWithRankEntity.find { StarWarsFilmsTable.name like "The%" }.map { it.name to it.rank } } - } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt index ccccc01e00..d8205b9cd5 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt @@ -5,9 +5,15 @@ import org.example.tables.StarWarsFilmsTable import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq class UpdateExamples { + fun updateFilmProperty() { + val movie = StarWarsFilmEntity.findById(2) + if (movie != null) { + movie.name = "Episode VIII – The Last Jedi" + } + } fun updateFilms() { // Find by id and update - val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(5) { + val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(MOVIE_ID) { it.name = "Episode VIII – The Last Jedi" } println(updatedMovie?.name) @@ -18,5 +24,4 @@ class UpdateExamples { } println(updatedMovie2?.name) } - } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt index 2c177b95ef..b0fb1d76e8 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt @@ -2,6 +2,8 @@ package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable +const val MAX_VARCHAR_LENGTH = 50 + object CitiesTable : IntIdTable() { - val name = varchar("name", 50) + val name = varchar("name", MAX_VARCHAR_LENGTH) } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsCustomTable.kt similarity index 55% rename from documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt rename to documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsCustomTable.kt index c83cf58bca..8756aede07 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CustomColumnTypeTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsCustomTable.kt @@ -4,9 +4,12 @@ import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.IdTable import org.jetbrains.exposed.sql.Column +const val MAX_ID_LENGTH = 32 +const val MAX_VARCHAR_LENGTH = 50 + object DirectorsCustomTable : IdTable() { - override val id: Column> = varchar("id", 32).entityId() - val name = varchar("name", 50) + override val id: Column> = varchar("id", MAX_ID_LENGTH).entityId() + val name = varchar("name", MAX_VARCHAR_LENGTH) override val primaryKey = PrimaryKey(id) } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt index 628c547486..8e112be7c3 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt @@ -2,10 +2,11 @@ package org.example.tables import org.jetbrains.exposed.dao.id.CompositeIdTable +const val MAX_VARCHAR_LENGTH = 32 enum class Genre { HORROR, DRAMA, THRILLER, SCI_FI } object DirectorsTable : CompositeIdTable("directors") { - val name = varchar("name", 50).entityId() + val name = varchar("name", MAX_VARCHAR_LENGTH).entityId() val guildId = uuid("guild_id").autoGenerate().entityId() val genre = enumeration("genre") diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt index 1a4f4c3904..a0795151fa 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt @@ -2,8 +2,10 @@ package org.example.tables import org.jetbrains.exposed.dao.id.CompositeIdTable +const val MAX_VARCHAR_LENGTH = 50 + object DirectorsWithGuildRefTable : CompositeIdTable() { - val name = varchar("name", 50).entityId() + val name = varchar("name", MAX_VARCHAR_LENGTH).entityId() val guildId = reference("guild_id", GuildsTable) val genre = enumeration("genre") diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/ComputedFieldTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsWFilmsWithRankTable.kt similarity index 80% rename from documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/ComputedFieldTable.kt rename to documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsWFilmsWithRankTable.kt index 1723f3eb59..53aac4044f 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/ComputedFieldTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsWFilmsWithRankTable.kt @@ -4,9 +4,11 @@ import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.Rank import org.jetbrains.exposed.sql.SortOrder +const val MAX_VARCHAR_LENGTH = 32 + object StarWarsWFilmsWithRankTable : IntIdTable() { val sequelId = integer("sequel_id").uniqueIndex() - val name = varchar("name", 50) + val name = varchar("name", MAX_VARCHAR_LENGTH) val rating = double("rating") val rank = Rank().over().orderBy(rating, SortOrder.DESC) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt index f40ec8687d..46abfc3475 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt @@ -2,7 +2,9 @@ package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable +const val MAX_VARCHAR_LENGTH = 50 + object UsersTable : IntIdTable() { - val name = varchar("name", 50) + val name = varchar("name", MAX_VARCHAR_LENGTH) val cityId = reference("cityId", CitiesTable.id) } diff --git a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic index 21f42be61b..be9757b71b 100644 --- a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic +++ b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic @@ -105,9 +105,7 @@

    You can update the value of a property just as you would with any property in a Kotlin class:

    - - movie.name = "Episode VIII – The Last Jedi" - + Exposed doesn't make an immediate update when you set a new value for Entity, it just stores it on the inner map. "Flushing" values to the database occurs at the end of the transaction, or before the next SELECT * from the database. @@ -150,10 +148,10 @@ searchQuery(). The results of the function can then be accessed through a property of the entity class:

    - + - - + +

    diff --git a/documentation-website/Writerside/topics/DAO-Table-Types.topic b/documentation-website/Writerside/topics/DAO-Table-Types.topic index 7aeb97363c..d68274e409 100644 --- a/documentation-website/Writerside/topics/DAO-Table-Types.topic +++ b/documentation-website/Writerside/topics/DAO-Table-Types.topic @@ -102,10 +102,10 @@

    - + - +

    From 992f61809b3442e8004f8d9d8c6eea8af86c4453 Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Thu, 3 Oct 2024 14:57:27 +0200 Subject: [PATCH 8/9] fix build errors, document referencing code examples and add comments --- .../Writerside/snippets/README.md | 58 ++++++++++++++++-- .../Writerside/snippets/exposed-dao/README.md | 14 +++++ .../src/main/kotlin/org/example/App.kt | 61 +++++++++++++------ .../org/example/examples/CreateExamples.kt | 13 ++-- .../org/example/examples/DeleteExamples.kt | 12 ++-- .../org/example/examples/ReadExamples.kt | 37 +++++++---- .../org/example/examples/UpdateExamples.kt | 8 ++- .../kotlin/org/example/tables/CitiesTable.kt | 4 +- .../example/tables/DirectorsCustomTable.kt | 4 +- .../org/example/tables/DirectorsTable.kt | 5 +- .../tables/DirectorsWithGuildRefTable.kt | 4 +- .../org/example/tables/StarWarsFilmsTable.kt | 15 +++-- .../tables/StarWarsWFilmsWithRankTable.kt | 4 +- .../kotlin/org/example/tables/UsersTable.kt | 4 +- .../topics/DAO-CRUD-Operations.topic | 11 +--- .../topics/DAO-Entity-definition.topic | 4 +- .../Writerside/topics/DAO-Table-Types.topic | 5 +- 17 files changed, 182 insertions(+), 81 deletions(-) diff --git a/documentation-website/Writerside/snippets/README.md b/documentation-website/Writerside/snippets/README.md index dd42d5a789..32b3f55935 100644 --- a/documentation-website/Writerside/snippets/README.md +++ b/documentation-website/Writerside/snippets/README.md @@ -17,15 +17,24 @@ Wait until IntelliJ IDEA builds and runs an example. ## Reference code snippets -To display a specific source file in a topic, use the `code-block` element with the `src` attribute as follows: +### Reference files and symbols -### XML +To display a specific source file in a topic, use the [`code-block`](https://www.jetbrains.com/help/writerside/semantic-markup-reference.html#code-block) +element with the `src` attribute. Whenever possible, reference the entire files or use the `include-symbol` attribute +to specify a class, method, or another symbol from the source file to include in the code block. + + +#### XML ````xml + + + + ```` -### Markdown +#### Markdown ```` ```kotlin @@ -33,7 +42,44 @@ To display a specific source file in a topic, use the `code-block` element with {src="exposed-dao/src/main/kotlin/org/example/StarWarsFilms.kt"} ```` -Use the following additional attributes: -- Use the `include-symbol` attribute to display only a specific function from the source file. -- Use the `include-lines` attribute to display specific lines from the source file. +### Reference by line numbers + +In cases where the example code is not assigned or is commented out, use the `include-lines` attribute to specify the line +numbers from the source file to include in the code block: + +#### XML + +```xml + + +``` +#### Markdown + +```` +```kotlin +``` +{src="exposed-dao/src/main/kotlin/org/example/StarWarsFilms.kt" include-lines="9-13"} +```` + +When using this approach, be sure to document it for future reference by adding a note about the explicitly referenced +lines, as shown in the example below: + +```kotlin +/* + ... + + Important: The SQL query is referenced by line number in `TOPIC_NAME.topic`. + If you add, remove, or modify any lines before the SELECT statement, ensure you update the corresponding + line numbers in the `code-block` element of the referenced file. + + CREATE TABLE IF NOT EXISTS STARWARSFILMS + (ID INT AUTO_INCREMENT PRIMARY KEY, + SEQUEL_ID INT NOT NULL, + "name" VARCHAR(50) NOT NULL, + DIRECTOR VARCHAR(50) NOT NULL); + */ +object StarWarsFilmsTable : IntIdTable() { + //... +} +``` diff --git a/documentation-website/Writerside/snippets/exposed-dao/README.md b/documentation-website/Writerside/snippets/exposed-dao/README.md index e1caa36b67..9eff5ab5d1 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/README.md +++ b/documentation-website/Writerside/snippets/exposed-dao/README.md @@ -1,6 +1,17 @@ # Exposed DAO API examples A Gradle application that shows how to work with Exposed DAO API. +The files are referenced in the DAO's [CRUD operations](../../topics/DAO-CRUD-Operations.topic), +[Table types](../../topics/DAO-Table-Types.topic) and [Entity definition](../../topics/DAO-Entity-definition.topic) +topics. + +## Build + +To build the application, in a terminal window navigate to the `snippets` folder and run the following command: + +```shell +./gradlew :exposed-dao:build +``` ## Run @@ -9,3 +20,6 @@ To run the application, in a terminal window navigate to the `snippets` folder a ```shell ./gradlew :exposed-dao:run ``` + +This will run queries to create new tables and run all functions in the `/examples` folder. +To only run a specific example, modify the `App.kt` file and re-run the project. diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt index a56a9583f1..56a7b633eb 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt @@ -1,11 +1,7 @@ package org.example import org.example.examples.* -import org.example.tables.CitiesTable -import org.example.tables.DirectorsTable -import org.example.tables.StarWarsFilmsTable -import org.example.tables.UserRatingsTable -import org.example.tables.UsersTable +import org.example.tables.* import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.StdOutSqlLogger @@ -17,18 +13,47 @@ fun main() { transaction { addLogger(StdOutSqlLogger) - SchemaUtils.create(StarWarsFilmsTable) - SchemaUtils.create(DirectorsTable) - SchemaUtils.create(UsersTable) - SchemaUtils.create(UserRatingsTable) - SchemaUtils.create(CitiesTable) - - // Create examples - val createExamples = CreateExamples() - createExamples.createFilms() - - // Read examples - val readExamples = ReadExamples() - readExamples.readExamples() + createTables() + runCreateExamples() + runReadExamples() + runUpdateExamples() + runDeleteExamples() } } + +fun createTables() { + SchemaUtils.create(StarWarsFilmsTable) + SchemaUtils.create(DirectorsTable) + SchemaUtils.create(UsersTable) + SchemaUtils.create(UserRatingsTable) + SchemaUtils.create(GuildsTable) + SchemaUtils.create(CitiesTable) + SchemaUtils.create(StarWarsWFilmsWithRankTable) +} + +fun runCreateExamples() { + val createExamples = CreateExamples() + createExamples.createFilms() + createExamples.createNewWithCompositeId() +} + +fun runReadExamples() { + val readExamples = ReadExamples() + readExamples.readAll() + readExamples.readWithJoin() + readExamples.find() + readExamples.findByCompositeId() + readExamples.queriesAsExpressions() +// readExamples.readComputedField() +} + +fun runUpdateExamples() { + val updateExamples = UpdateExamples() + updateExamples.updateFilms() + updateExamples.updateFilmProperty() +} + +fun runDeleteExamples() { + val deleteExamples = DeleteExamples() + deleteExamples.deleteFilm() +} diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt index 1401e1f876..a87711d956 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/CreateExamples.kt @@ -7,27 +7,28 @@ import org.example.tables.Genre import org.jetbrains.exposed.dao.id.CompositeID import java.util.* -const val MOVIE_SEQUELID = 8 -const val MOVIE2_SEQUELID = 9 +const val MOVIE_SEQUEL_ID = 8 +const val MOVIE2_SEQUEL_ID = 9 class CreateExamples { fun createFilms() { val movie = StarWarsFilmEntity.new { name = "The Last Jedi" - sequelId = MOVIE_SEQUELID + sequelId = MOVIE_SEQUEL_ID director = "Rian Johnson" } - println(movie) + println("Created a new record with name " + movie.name) // Create a new record with id val movie2 = StarWarsFilmEntity.new(id = 2) { name = "The Rise of Skywalker" - sequelId = MOVIE2_SEQUELID + sequelId = MOVIE2_SEQUEL_ID director = "J.J. Abrams" } - println(movie2) + println("Created a new record with id " + movie2.id) } + // Create a new record with a composite id fun createNewWithCompositeId() { val directorId = CompositeID { it[DirectorsTable.name] = "J.J. Abrams" diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt index 8c44384644..c79d738304 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt @@ -2,16 +2,12 @@ package org.example.examples import org.example.entities.StarWarsFilmEntity -const val SEQUEL_ID = 8 - class DeleteExamples { fun deleteFilm() { - val movie = StarWarsFilmEntity.new { - name = "The Last Jedi" - sequelId = SEQUEL_ID - director = "Rian Johnson" + val movie = StarWarsFilmEntity.findById(2) + if (movie != null) { + val deletedMovie = movie.delete() + println(deletedMovie) } - val deletedMovie = movie.delete() - println(deletedMovie) } } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt index 0358edeeae..df0985a0fb 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt @@ -1,14 +1,7 @@ package org.example.examples -import org.example.entities.DirectorEntity -import org.example.entities.StarWarsFilmEntity -import org.example.entities.StarWarsWFilmWithRankEntity -import org.example.entities.UserEntity -import org.example.tables.CitiesTable -import org.example.tables.DirectorsTable -import org.example.tables.StarWarsFilmsTable -import org.example.tables.UserRatingsTable -import org.example.tables.UsersTable +import org.example.entities.* +import org.example.tables.* import org.jetbrains.exposed.dao.id.CompositeID import org.jetbrains.exposed.sql.SortOrder import org.jetbrains.exposed.sql.and @@ -23,6 +16,7 @@ const val MIN_MOVIE_RATING = 5 const val MOVIE_RATING = 4.2 class ReadExamples { + fun readAll() { // Read all movies val allMovies = StarWarsFilmEntity.all() @@ -44,7 +38,7 @@ class ReadExamples { if (movie != null) { // Read a property value val movieName = movie.name - println("Created a new film named $movieName") + println("Created a new movie with name $movieName") // Read the id value val movieId: Int = movie.id.value @@ -53,7 +47,7 @@ class ReadExamples { // Read all with a condition val specificMovie = StarWarsFilmEntity.find { StarWarsFilmsTable.sequelId eq MOVIE_SEQUELID } - specificMovie.forEach({ println("Found a movie with sequelId 8 and name " + it.name) }) + specificMovie.forEach({ println("Found a movie with sequelId " + MOVIE_SEQUELID + " and name " + it.name) }) } // Read an entity with a join to another table @@ -68,13 +62,30 @@ class ReadExamples { users.map { println(it.name) } } + /* + Find records by composite id. + + Important: The SQL query is referenced by line number in `DAO-CRUD-operations.topic`. + If you add, remove, or modify any lines before the SELECT statement, ensure you update the corresponding + line numbers in the `code-block` element of the referenced file. + + SELECT DIRECTORS."name", DIRECTORS.GUILD_ID, DIRECTORS.GENRE + FROM DIRECTORS + WHERE (DIRECTORS."name" = 'J.J. Abrams') + AND (DIRECTORS.GUILD_ID = '2cc64f4f-1a2c-41ce-bda1-ee492f787f4b') + */ fun findByCompositeId() { - // Find records by composite id val directorId = CompositeID { it[DirectorsTable.name] = "J.J. Abrams" it[DirectorsTable.guildId] = UUID.randomUUID() } + DirectorEntity.new(directorId) { + genre = Genre.SCI_FI + } + + val director = DirectorEntity.findById(directorId) + println("Found director $director") val directors = DirectorEntity.find { DirectorsTable.id eq directorId } directors.forEach({ println(it.genre) }) } @@ -103,6 +114,6 @@ class ReadExamples { rating = MOVIE_RATING } - StarWarsWFilmWithRankEntity.find { StarWarsFilmsTable.name like "The%" }.map { it.name to it.rank } + StarWarsWFilmWithRankEntity.find { StarWarsWFilmsWithRankTable.name like "The%" }.map { it.name to it.rank } } } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt index d8205b9cd5..d4ef3b8cf0 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/UpdateExamples.kt @@ -8,12 +8,18 @@ class UpdateExamples { fun updateFilmProperty() { val movie = StarWarsFilmEntity.findById(2) if (movie != null) { + /* + Important: The `movie.name` statement is referenced by line number in `DAO-CRUD-operations.topic`. + If you add, remove, or modify any lines prior to this one, ensure you update the corresponding + line numbers in the `code-block` element of the referenced file. + */ movie.name = "Episode VIII – The Last Jedi" + println("The movie has been renamed to ${movie.name}") } } fun updateFilms() { // Find by id and update - val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(MOVIE_ID) { + val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(2) { it.name = "Episode VIII – The Last Jedi" } println(updatedMovie?.name) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt index b0fb1d76e8..171dc956e3 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/CitiesTable.kt @@ -2,8 +2,8 @@ package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable -const val MAX_VARCHAR_LENGTH = 50 +const val MAX_CITY_NAME_LENGTH = 50 object CitiesTable : IntIdTable() { - val name = varchar("name", MAX_VARCHAR_LENGTH) + val name = varchar("name", MAX_CITY_NAME_LENGTH) } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsCustomTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsCustomTable.kt index 8756aede07..d966dd5d47 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsCustomTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsCustomTable.kt @@ -5,11 +5,11 @@ import org.jetbrains.exposed.dao.id.IdTable import org.jetbrains.exposed.sql.Column const val MAX_ID_LENGTH = 32 -const val MAX_VARCHAR_LENGTH = 50 +const val MAX_DIRECTOR_NAME_LENGTH = 32 object DirectorsCustomTable : IdTable() { override val id: Column> = varchar("id", MAX_ID_LENGTH).entityId() - val name = varchar("name", MAX_VARCHAR_LENGTH) + val name = varchar("name", MAX_DIRECTOR_NAME_LENGTH) override val primaryKey = PrimaryKey(id) } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt index 8e112be7c3..7dc9a7357e 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsTable.kt @@ -2,11 +2,12 @@ package org.example.tables import org.jetbrains.exposed.dao.id.CompositeIdTable -const val MAX_VARCHAR_LENGTH = 32 enum class Genre { HORROR, DRAMA, THRILLER, SCI_FI } +const val NAME_LENGTH = 50 + object DirectorsTable : CompositeIdTable("directors") { - val name = varchar("name", MAX_VARCHAR_LENGTH).entityId() + val name = varchar("name", NAME_LENGTH).entityId() val guildId = uuid("guild_id").autoGenerate().entityId() val genre = enumeration("genre") diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt index a0795151fa..84e5d0b14b 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/DirectorsWithGuildRefTable.kt @@ -2,10 +2,10 @@ package org.example.tables import org.jetbrains.exposed.dao.id.CompositeIdTable -const val MAX_VARCHAR_LENGTH = 50 +const val DIRECTOR_NAME_LENGTH = 50 object DirectorsWithGuildRefTable : CompositeIdTable() { - val name = varchar("name", MAX_VARCHAR_LENGTH).entityId() + val name = varchar("name", DIRECTOR_NAME_LENGTH).entityId() val guildId = reference("guild_id", GuildsTable) val genre = enumeration("genre") diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt index 99f07d68e8..4c40e06e44 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsFilmsTable.kt @@ -5,12 +5,17 @@ import org.jetbrains.exposed.dao.id.IntIdTable const val MAX_VARCHAR_LENGTH = 50 /* -CREATE TABLE IF NOT EXISTS STARWARSFILMS -(ID INT AUTO_INCREMENT PRIMARY KEY, -SEQUEL_ID INT NOT NULL, -"name" VARCHAR(50) NOT NULL, -DIRECTOR VARCHAR(50) NOT NULL); + Important: This file is referenced by line number in `DAO-Table-Types.topic`. + If you add, remove, or modify any lines, ensure you update the corresponding + line numbers in the `code-block` element of the referenced file. + + CREATE TABLE IF NOT EXISTS STARWARSFILMS + (ID INT AUTO_INCREMENT PRIMARY KEY, + SEQUEL_ID INT NOT NULL, + "name" VARCHAR(50) NOT NULL, + DIRECTOR VARCHAR(50) NOT NULL); */ + object StarWarsFilmsTable : IntIdTable() { val sequelId = integer("sequel_id").uniqueIndex() val name = varchar("name", MAX_VARCHAR_LENGTH) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsWFilmsWithRankTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsWFilmsWithRankTable.kt index 53aac4044f..1202bb4954 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsWFilmsWithRankTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/StarWarsWFilmsWithRankTable.kt @@ -4,11 +4,11 @@ import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.Rank import org.jetbrains.exposed.sql.SortOrder -const val MAX_VARCHAR_LENGTH = 32 +const val MAX_NAME_LENGTH = 32 object StarWarsWFilmsWithRankTable : IntIdTable() { val sequelId = integer("sequel_id").uniqueIndex() - val name = varchar("name", MAX_VARCHAR_LENGTH) + val name = varchar("name", MAX_NAME_LENGTH) val rating = double("rating") val rank = Rank().over().orderBy(rating, SortOrder.DESC) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt index 46abfc3475..05de541ff7 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/tables/UsersTable.kt @@ -2,9 +2,9 @@ package org.example.tables import org.jetbrains.exposed.dao.id.IntIdTable -const val MAX_VARCHAR_LENGTH = 50 +const val MAX_USER_NAME_LENGTH = 50 object UsersTable : IntIdTable() { - val name = varchar("name", MAX_VARCHAR_LENGTH) + val name = varchar("name", MAX_USER_NAME_LENGTH) val cityId = reference("cityId", CitiesTable.id) } diff --git a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic index be9757b71b..774796bf51 100644 --- a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic +++ b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic @@ -66,16 +66,11 @@ all composite columns and to get entities, much like the id column of its associated CompositeIdTable:

    - +

    The SQL query would result in something like the following:

    - + For a list of available predicates, see
    DSL Where expression. @@ -105,7 +100,7 @@

    You can update the value of a property just as you would with any property in a Kotlin class:

    - + Exposed doesn't make an immediate update when you set a new value for Entity, it just stores it on the inner map. "Flushing" values to the database occurs at the end of the transaction, or before the next SELECT * from the database. diff --git a/documentation-website/Writerside/topics/DAO-Entity-definition.topic b/documentation-website/Writerside/topics/DAO-Entity-definition.topic index a73c8bc491..0f699044c7 100644 --- a/documentation-website/Writerside/topics/DAO-Entity-definition.topic +++ b/documentation-website/Writerside/topics/DAO-Entity-definition.topic @@ -19,10 +19,10 @@

    - + - + diff --git a/documentation-website/Writerside/topics/DAO-Table-Types.topic b/documentation-website/Writerside/topics/DAO-Table-Types.topic index d68274e409..b317bc66b1 100644 --- a/documentation-website/Writerside/topics/DAO-Table-Types.topic +++ b/documentation-website/Writerside/topics/DAO-Table-Types.topic @@ -51,7 +51,8 @@

    The following example represents a table with custom columns sequel_id, name, and director:

    - +

    The IntIdTable class automatically generates an auto-incrementing integer id @@ -60,7 +61,7 @@ When the table is created, it corresponds to the following SQL query:

    - +

    For more information on defining and configuring tables in Exposed, see .

    From 5b9890a392b7febb11fcb701632bd037bfa082e5 Mon Sep 17 00:00:00 2001 From: Viktoriya Nikolova Date: Fri, 4 Oct 2024 18:35:41 +0200 Subject: [PATCH 9/9] fix readComputedField() and delete code examples --- .../src/main/kotlin/org/example/App.kt | 9 +++++++-- .../org/example/examples/DeleteExamples.kt | 10 ++++++++-- .../kotlin/org/example/examples/ReadExamples.kt | 17 ++++++++++++----- .../Writerside/topics/DAO-CRUD-Operations.topic | 4 ++-- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt index 56a7b633eb..d00253991e 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/App.kt @@ -3,13 +3,18 @@ package org.example import org.example.examples.* import org.example.tables.* import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.DatabaseConfig import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.StdOutSqlLogger import org.jetbrains.exposed.sql.addLogger import org.jetbrains.exposed.sql.transactions.transaction fun main() { - Database.connect("jdbc:h2:mem:test", driver = "org.h2.Driver") + Database.connect( + "jdbc:h2:mem:test", + "org.h2.Driver", + databaseConfig = DatabaseConfig { useNestedTransactions = true } + ) transaction { addLogger(StdOutSqlLogger) @@ -44,7 +49,7 @@ fun runReadExamples() { readExamples.find() readExamples.findByCompositeId() readExamples.queriesAsExpressions() -// readExamples.readComputedField() + readExamples.readComputedField() } fun runUpdateExamples() { diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt index c79d738304..ef7420f92d 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/DeleteExamples.kt @@ -3,11 +3,17 @@ package org.example.examples import org.example.entities.StarWarsFilmEntity class DeleteExamples { +/* + Delete a record. + + Important: The `movie.delete` statement is referenced by line number in `DAO-CRUD-operations.topic`. + If you add, remove, or modify any lines prior to this one, ensure you update the corresponding + line numbers in the `code-block` element of the referenced file. +*/ fun deleteFilm() { val movie = StarWarsFilmEntity.findById(2) if (movie != null) { - val deletedMovie = movie.delete() - println(deletedMovie) + movie.delete() } } } diff --git a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt index df0985a0fb..3ccd6e6934 100644 --- a/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt +++ b/documentation-website/Writerside/snippets/exposed-dao/src/main/kotlin/org/example/examples/ReadExamples.kt @@ -8,6 +8,7 @@ import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.count import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.wrapAsExpression import java.util.* @@ -108,12 +109,18 @@ class ReadExamples { } fun readComputedField() { - StarWarsWFilmWithRankEntity.new { - sequelId = MOVIE_SEQUELID - name = "The Last Jedi" - rating = MOVIE_RATING + transaction { + StarWarsWFilmWithRankEntity.new { + sequelId = MOVIE_SEQUELID + name = "The Last Jedi" + rating = MOVIE_RATING + } } - StarWarsWFilmWithRankEntity.find { StarWarsWFilmsWithRankTable.name like "The%" }.map { it.name to it.rank } + transaction { + StarWarsWFilmWithRankEntity + .find { StarWarsWFilmsWithRankTable.name like "The%" } + .map { it.name to it.rank } + } } } diff --git a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic index 774796bf51..f9b4f1b1c0 100644 --- a/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic +++ b/documentation-website/Writerside/topics/DAO-CRUD-Operations.topic @@ -70,7 +70,7 @@

    The SQL query would result in something like the following:

    - + For a list of available predicates, see
    DSL Where expression. @@ -124,7 +124,7 @@

    To delete a record, use the delete() function:

    - +