Skip to content

Commit

Permalink
Rename the SQL DSL functions taking mapper parameters, adding "withMa…
Browse files Browse the repository at this point in the history
…pper" prefixes

Resolve #6

Two "delete" functions were mistakenly added in this file and its `com.huanshankeji.exposedvertxsqlclient.sql.mapping` package, and are now moved out into `com.huanshankeji.exposedvertxsqlclient.sql`. A TODO is removed with its content moved into README.md.
  • Loading branch information
ShreckYe committed Nov 14, 2024
1 parent 31629f3 commit a105a4d
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 47 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ withContext(Dispatchers.IO) {

#### Core APIs

With these core APIs, you create and execute Exposed `Statement`s. You don't need to learn many new APIs, and the `Statement`s are more composable and easily editable.
With these core APIs, you create and execute Exposed `Statement`s. You don't need to learn many new APIs, and the
`Statement`s are more composable and easily editable. For example, you can move a query into an adapted subquery.

```kotlin
// The Exposed `Table` extension functions `insert`, `update`, and `delete` execute eagerly so `insertStatement`, `updateStatement`, `deleteStatement` have to be used.
Expand Down Expand Up @@ -109,16 +110,16 @@ Please read [that library's basic usage guide](https://github.com/huanshankeji/e
```kotlin
val directorId = 1
val director = Director(directorId, "George Lucas")
databaseClient.insert(Directors, director, Mappers.director)
databaseClient.insertWithMapper(Directors, director, Mappers.director)

val episodeIFilmDetails = FilmDetails(1, "Star Wars: Episode I – The Phantom Menace", directorId)
// insert without the ID since it's `AUTO_INCREMENT`
databaseClient.insert(Films, episodeIFilmDetails, Mappers.filmDetailsWithDirectorId)
databaseClient.insertWithMapper(Films, episodeIFilmDetails, Mappers.filmDetailsWithDirectorId)

val filmId = 2
val episodeIIFilmDetails = FilmDetails(2, "Star Wars: Episode II – Attack of the Clones", directorId)
val filmWithDirectorId = FilmWithDirectorId(filmId, episodeIIFilmDetails)
databaseClient.insert(Films, filmWithDirectorId, Mappers.filmWithDirectorId) // insert with the ID
databaseClient.insertWithMapper(Films, filmWithDirectorId, Mappers.filmWithDirectorId) // insert with the ID

val fullFilms = databaseClient.selectWithMapper(filmsLeftJoinDirectors, Mappers.fullFilm) {
where(Films.filmId inList listOf(1, 2)) // This API still depends on the old SELECT DSL and will be refactored.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,14 @@ suspend fun <T : Table, E, SelectorResultT : Comparable<SelectorResultT>> Databa
where: BuildWhere? = null, limit: Int? = null, body: T.(UpdateStatement, E) -> Unit
) =
batchUpdate(table, data.sortedBy(selector), where, limit, body)


suspend fun <T : Table> DatabaseClient<*>.deleteWhere(
table: T, limit: Int? = null, offset: Long? = null, op: T.(ISqlExpressionBuilder) -> Op<Boolean>
) =
executeUpdate(table.deleteWhereStatement(limit, offset, op))

suspend fun <T : Table> DatabaseClient<*>.deleteIgnoreWhere(
table: T, limit: Int? = null, offset: Long? = null, op: T.(ISqlExpressionBuilder) -> Op<Boolean>
) =
executeUpdate(table.deleteIgnoreWhereStatement(limit, offset, op))
Original file line number Diff line number Diff line change
@@ -1,63 +1,48 @@
@file:OptIn(InternalApi::class)

package com.huanshankeji.exposedvertxsqlclient.sql.mapping

import com.huanshankeji.InternalApi
import com.huanshankeji.exposed.BuildWhere
import com.huanshankeji.exposed.SELECT_DSL_DEPRECATION_MESSAGE
import com.huanshankeji.exposed.datamapping.DataQueryMapper
import com.huanshankeji.exposed.datamapping.DataUpdateMapper
import com.huanshankeji.exposed.datamapping.updateBuilderSetter
import com.huanshankeji.exposed.deleteIgnoreWhereStatement
import com.huanshankeji.exposed.deleteWhereStatement
import com.huanshankeji.exposedvertxsqlclient.DatabaseClient
import com.huanshankeji.exposedvertxsqlclient.ExperimentalEvscApi
import com.huanshankeji.exposedvertxsqlclient.sql.*
import com.huanshankeji.vertx.sqlclient.datamapping.RowDataQueryMapper
import io.vertx.sqlclient.RowSet
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.ColumnSet
import org.jetbrains.exposed.sql.Query
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.statements.UpdateBuilder

// TODO move to a separate module
// TODO Note that using these DSLs reduces the composability of statements, for example, when moving a query into a subquery. (this statement can be moved into docs some day)

@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.executeQuery(
suspend fun <Data : Any> DatabaseClient<*>.executeQueryWithMapper(
query: Query,
dataQueryMapper: DataQueryMapper<Data>
): RowSet<Data> =
executeWithMapping(query) { row -> dataQueryMapper.resultRowToData(row.toExposedResultRowWithTransaction(query)) }

@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.executeVertxSqlClientRowQuery(
suspend fun <Data : Any> DatabaseClient<*>.executeVertxSqlClientRowQueryWithMapper(
query: Query, rowDataQueryMapper: RowDataQueryMapper<Data>
): RowSet<Data> =
executeWithMapping(query, rowDataQueryMapper::rowToData)

@Deprecated(
SELECT_DSL_DEPRECATION_MESSAGE,
ReplaceWith("this.selectWithMapper<Data>(columnSet, dataQueryMapper, buildQuery)")
)
@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.select(
columnSet: ColumnSet, dataQueryMapper: DataQueryMapper<Data>, buildQuery: FieldSet.() -> Query
) =
executeQuery(columnSet.slice(dataQueryMapper.neededColumns).buildQuery(), dataQueryMapper)

@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.selectWithMapper(
columnSet: ColumnSet, dataQueryMapper: DataQueryMapper<Data>, buildQuery: Query.() -> Query
) =
executeQuery(columnSet.select(dataQueryMapper.neededColumns).buildQuery(), dataQueryMapper)
executeQueryWithMapper(columnSet.select(dataQueryMapper.neededColumns).buildQuery(), dataQueryMapper)

@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.insert(
suspend fun <Data : Any> DatabaseClient<*>.insertWithMapper(
table: Table, data: Data, dataUpdateMapper: DataUpdateMapper<Data>
) =
insert(table, dataUpdateMapper.updateBuilderSetter(data))

@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.insertIgnore(
suspend fun <Data : Any> DatabaseClient<*>.insertIgnoreWithMapper(
table: Table, data: Data, dataUpdateMapper: DataUpdateMapper<Data>
) =
insertIgnore(table, dataUpdateMapper.updateBuilderSetter(data))
Expand All @@ -70,13 +55,13 @@ fun <Data : Any, ColumnSetT : ColumnSet> DataUpdateMapper<Data>.batchUpdateBuild
// TODO: consider removing the table param by adding it to `DataUpdateMapper`

@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.batchInsert(
suspend fun <Data : Any> DatabaseClient<*>.batchInsertWithMapper(
table: Table, data: Iterable<Data>, dataUpdateMapper: DataUpdateMapper<Data>
) =
batchInsert(table, data, dataUpdateMapper.batchUpdateBuilderSetter())

@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.batchInsertIgnore(
suspend fun <Data : Any> DatabaseClient<*>.batchInsertIgnoreWithMapper(
table: Table, data: Iterable<Data>, dataUpdateMapper: DataUpdateMapper<Data>
) =
batchInsertIgnore(table, data, dataUpdateMapper.batchUpdateBuilderSetter())
Expand All @@ -86,17 +71,7 @@ suspend fun <Data : Any> DatabaseClient<*>.batchInsertIgnore(
* In most cases you should specify the fields to update in a more detailed way instead of using this function.
*/
@ExperimentalEvscApi
suspend fun <Data : Any> DatabaseClient<*>.update(
suspend fun <Data : Any> DatabaseClient<*>.updateWithMapper(
table: Table, where: BuildWhere? = null, limit: Int? = null, data: Data, dataUpdateMapper: DataUpdateMapper<Data>
) =
update(table, where, limit, dataUpdateMapper.updateBuilderSetter(data))

suspend fun <T : Table> DatabaseClient<*>.deleteWhere(
table: T, limit: Int? = null, offset: Long? = null, op: T.(ISqlExpressionBuilder) -> Op<Boolean>
) =
executeUpdate(table.deleteWhereStatement(limit, offset, op))

suspend fun <T : Table> DatabaseClient<*>.deleteIgnoreWhere(
table: T, limit: Int? = null, offset: Long? = null, op: T.(ISqlExpressionBuilder) -> Op<Boolean>
) =
executeUpdate(table.deleteIgnoreWhereStatement(limit, offset, op))
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ package com.huanshankeji.exposedvertxsqlclient

import com.huanshankeji.exposed.*
import com.huanshankeji.exposedvertxsqlclient.sql.*
import com.huanshankeji.exposedvertxsqlclient.sql.mapping.deleteIgnoreWhere
import com.huanshankeji.exposedvertxsqlclient.sql.mapping.deleteWhere
import io.vertx.core.Vertx
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.selectAll

object Examples : IntIdTable("examples") {
val name = varchar("name", 64)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.huanshankeji.exposedvertxsqlclient

import com.huanshankeji.exposed.datamapping.classproperty.PropertyColumnMappingConfig
import com.huanshankeji.exposed.datamapping.classproperty.reflectionBasedClassPropertyDataMapper
import com.huanshankeji.exposedvertxsqlclient.sql.mapping.insert
import com.huanshankeji.exposedvertxsqlclient.sql.mapping.insertWithMapper
import com.huanshankeji.exposedvertxsqlclient.sql.mapping.selectWithMapper
import io.vertx.sqlclient.Pool
import org.jetbrains.exposed.dao.id.IntIdTable
Expand Down Expand Up @@ -83,16 +83,16 @@ object Mappers {
suspend fun mappingExamples(databaseClient: DatabaseClient<Pool>) {
val directorId = 1
val director = Director(directorId, "George Lucas")
databaseClient.insert(Directors, director, Mappers.director)
databaseClient.insertWithMapper(Directors, director, Mappers.director)

val episodeIFilmDetails = FilmDetails(1, "Star Wars: Episode I – The Phantom Menace", directorId)
// insert without the ID since it's `AUTO_INCREMENT`
databaseClient.insert(Films, episodeIFilmDetails, Mappers.filmDetailsWithDirectorId)
databaseClient.insertWithMapper(Films, episodeIFilmDetails, Mappers.filmDetailsWithDirectorId)

val filmId = 2
val episodeIIFilmDetails = FilmDetails(2, "Star Wars: Episode II – Attack of the Clones", directorId)
val filmWithDirectorId = FilmWithDirectorId(filmId, episodeIIFilmDetails)
databaseClient.insert(Films, filmWithDirectorId, Mappers.filmWithDirectorId) // insert with the ID
databaseClient.insertWithMapper(Films, filmWithDirectorId, Mappers.filmWithDirectorId) // insert with the ID

val fullFilms = databaseClient.selectWithMapper(filmsLeftJoinDirectors, Mappers.fullFilm) {
where(Films.filmId inList listOf(1, 2)) // This API still depends on the old SELECT DSL and will be refactored.
Expand Down

0 comments on commit a105a4d

Please sign in to comment.