In the Alias class, there is a method `operator fu...
# exposed
d
In the Alias class, there is a method
operator 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.
Hmm, this is also a nice mini-dsl:
Copy code
import 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:
Copy code
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) }
        )
}