Search code examples
kotlinkotlin-exposed

How can I access values from a min(), max() expression in Kotlin Exposed?


I'm trying to get the min and max date for a set of SQL rows from my database. When I run this transaction in Exposed in debug mode I see the correct dates are fetched from the database but when I try to access them with: row[MetricValues.date.min()] it is showing up typed as Nothing and throwing an error when I try and use it.

object MetricValues : Table("metric_values") {
    val id = integer("id").autoIncrement()
    val metricDefinitionId = reference(
        "metric_definition_id",
        MetricDefinitions.id,
        onDelete = ReferenceOption.CASCADE,
        onUpdate = ReferenceOption.CASCADE
    )
    val adId = reference(
        "ad_id",
        Ads.id,
        onDelete = ReferenceOption.CASCADE,
        onUpdate = ReferenceOption.CASCADE
    )
    val date = datetime("date")
    val value = double("value")

    override val primaryKey = PrimaryKey(id)
}

--

val result = newSuspendedTransaction(Dispatchers.IO, client) {
            MetricValues
                .select(MetricValues.adId, MetricValues.date.min(), MetricValues.date.max())
                .where {
                    MetricValues.adId inList (adIds.map { UUID.fromString(it) })
                }
                .groupBy(MetricValues.adId)
                .associate { row ->
                    MetricValues.adId.toString() to getDifferenceInDays(
                        row[MetricValues.date.min()],
                        row[MetricValues.date.max()]
                    )
                }
        }

I've tried using the Max and Min functions as well which didn't work. I also tried just ignoring the type error with (!!) which has worked in the past when I have the same issue with the sum() function but did not work here.


Solution

  • Just extract the expression into a variable and use it when access row:

    val minDate = MetricValues.date.min()
    val maxDate = MetricValues.date.max()
    MetricValues
        .select(MetricValues.adId, minDate , maxDate)
        .where {
            MetricValues.adId inList (adIds.map { UUID.fromString(it) })
        }
        .groupBy(MetricValues.adId)
        .associate { row ->
            MetricValues.adId.toString() to getDifferenceInDays(
                row[minDate],
                row[maxDate]
            )
        }