Last active
June 3, 2017 00:31
-
-
Save thomasnield/9c391a588af04c49747d3a2224db285c to your computer and use it in GitHub Desktop.
JDBC ResultSet to Data Class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Bring in Google Guava as a dependency | |
| // compile 'com.google.guava:guava:22.0' | |
| import com.google.common.base.CaseFormat | |
| import java.sql.ResultSet | |
| fun ResultSet.toDataClass(): String { | |
| val table = metaData.getTableName(1).let { it.substring(0,1) + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, it.substring(1)) } | |
| val headers = (1..metaData.columnCount).asSequence() | |
| .map { metaData.getColumnName(it) } | |
| .toList() | |
| val types = (1..metaData.columnCount).asSequence() | |
| .map { | |
| it to when { | |
| metaData.getColumnClassName(it).contains(".Integer") -> "Int" | |
| metaData.getColumnClassName(it).contains(".String") -> "String" | |
| metaData.getColumnClassName(it).contains(".Date") -> "LocalDate" | |
| metaData.getColumnClassName(it).contains(".Timestamp") -> "LocalDateTime" | |
| metaData.getColumnClassName(it).contains(".BigDecimal") -> "BigDecimal" | |
| metaData.getColumnClassName(it).contains(".Long") -> "Long" | |
| else -> "String" | |
| } | |
| }.map { if (metaData.isNullable(it.first) == 1) "${it.second}?" else it.second } | |
| .toList() | |
| fun buildField(index: Int) = " val ${CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, headers[index])}: ${types[index]}" | |
| val parameters = headers.map { CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, it) } | |
| val tableFields = (0..(headers.size - 1)).asSequence().map { buildField(it) }.joinToString(",\n") | |
| data class TypeHeaderParameter(val type: String, val header: String, val parameter: String) | |
| val resultSetConstructor = types.asSequence().zip(headers.asSequence()).zip(parameters.asSequence()) | |
| .map { TypeHeaderParameter(it.first.first, it.first.second, it.second) } | |
| .map { thp -> | |
| val header = "\"${thp.header}\"" | |
| val parameter = "${thp.parameter} =" | |
| when(thp.type.replace("?","")) { | |
| "Int" -> "$parameter rs.getInt($header)" | |
| "String" -> "$parameter rs.getString($header)" | |
| "LocalDate" -> "$parameter rs.getLocalDate($header)" | |
| "LocalDateTime" -> "$parameter rs.getLocalDateTime($header)" | |
| "BigDecimal" -> "$parameter rs.getBigDecimal($header)" | |
| "Long" -> "$parameter rs.getLong($header)" | |
| else -> throw Exception("Unmapped type!") | |
| } | |
| }.joinToString(",\n ").let { "constructor(rs: ResultSet): this(\n $it\n)"} | |
| return "data class $table (\n$tableFields\n) {\n $resultSetConstructor \n}" | |
| } | |
| fun ResultSet.getLocalDate(colName: String) = this.getDate(colName)?.toLocalDate() | |
| fun ResultSet.getLocalDate(colIndex: Int) = this.getDate(colIndex)?.toLocalDate() | |
| fun ResultSet.getLocalDateTime(colName: String) = this.getTimestamp(colName)?.toLocalDateTime() | |
| fun ResultSet.getLocalDateTime(colIndex: Int) = this.getTimestamp(colIndex)?.toLocalDateTime() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment