Daniel Pitts
11/02/2024, 3:23 PMoperator fun <T : Any?> get(original: Column<T>): Column<T>
. I think it would be nice to promote that method to the Table class, and make it open
. That way , I can write a generic realColumn(tableOrAlias: Table) = tableOrAlias[tableColumn]
for some of my cases.Daniel Pitts
11/02/2024, 3:37 PMimport org.jetbrains.exposed.sql.*
sealed interface ColumnMapper<T : Table> {
operator fun <C> invoke(columnSelect: T.() -> Column<C>): Column<C>
}
fun <T : Table> mapper(table: T): ColumnMapper<T> = TableColumnMapper(table)
fun <T : Table> mapper(alias: Alias<T>): ColumnMapper<T> = AliasColumnMapper(alias)
private class AliasColumnMapper<T : Table>(
private val alias: Alias<T>,
) : ColumnMapper<T> {
override fun <C> invoke(columnSelect: T.() -> Column<C>): Column<C> =
alias.delegate
.columnSelect()
.let { alias[it] }
}
private class TableColumnMapper<T : Table>(
private val table: T,
) : ColumnMapper<T> {
override fun <C> invoke(columnSelect: T.() -> Column<C>): Column<C> =
table
.columnSelect()
.also { require(it in table.columns) { "Column not in table" } }
}
Example usage:
data class ByTagName(
val tagName: String,
) : NoteQuery {
override fun join(
join: Join,
noteVersion: ColumnMapper<Tables.NoteVersion>,
) = join
.innerJoin(
Tables.NoteVersionTag,
additionalConstraint = {
noteVersion { noteId }.eq(Tables.NoteVersionTag.noteId) and
noteVersion { versionId }.eq(Tables.NoteVersionTag.version)
}
).innerJoin(
Tables.Tag,
additionalConstraint = { Tables.NoteVersionTag.tagId.eq(Tables.Tag.id) and Tables.Tag.name.eq(tagName) }
)
}