Something like
getConnection().use { connection ->
connection.createStatement().use { statement ->
statement.executeQuery(sql).use { resultSet ->
while (resultSet.next()) { ... }
}
}
}
looks weird with multiple nested levels for multiple resources. I rolled my own simple implementation for multiple resources:
class Resources : AutoCloseable {
val resources = mutableListOf<AutoCloseable>()
fun <T: AutoCloseable> T.use(): T {
resources += this
return this
}
override fun close() {
var exception: Exception? = null
for (resource in resources.reversed()) {
try {
resource.close()
} catch (closeException: Exception) {
if (exception == null) {
exception = closeException
} else {
exception.addSuppressed(closeException)
}
}
}
if (exception != null) throw exception
}
}
inline fun <T> withResources(block: Resources.() -> T): T = Resources().use(block)
which could be used:
withResources {
val connection = getConnection().use()
val statement = connection.createStatement().use()
val resultSet = statement.executeQuery(sql).use()
while (resultSet.next()) { ... }
}
This works for me, but I wonder if there’s better way with standard library or something like that.