From 7137872ede23b4288c97cc65482e56d1515087dd Mon Sep 17 00:00:00 2001 From: James Strachan Date: Wed, 14 Mar 2012 20:44:54 +0000 Subject: [PATCH] moved the jdbc string template API out of the test case :) and fix up some cruft in the API docs --- .../main/kotlin/kotlin/jdbc/Connections.kt | 167 ++++++++++++++++- .../main/kotlin/kotlin/jdbc/DataSources.kt | 17 +- .../test/kotlin/jdbc/JdbcTemplateTest.kt | 170 +----------------- .../jetbrains/kotlin/site/GenerateSiteTest.kt | 4 + 4 files changed, 187 insertions(+), 171 deletions(-) diff --git a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Connections.kt b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Connections.kt index c80e63f03c7..41ad699fc96 100644 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Connections.kt +++ b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Connections.kt @@ -1,6 +1,8 @@ package kotlin.jdbc import java.sql.* +import kotlin.template.StringTemplate +import java.math.BigDecimal /** * Helper method to process a statement on this collection @@ -21,6 +23,15 @@ fun Connection.update(sql: String): Int { return statement{ it.executeUpdate(sql) } } +/** + * Performs the SQL update using the [[StringTemplate]] + */ +fun Connection.update(template : StringTemplate) : Int { + val preparedStatement = prepare(template) + return preparedStatement.update() +} + + /** * Perform a query on the connection and processes the result set with a function */ @@ -33,4 +44,158 @@ fun Connection.query(sql: String, block: (ResultSet) -> T): T { throw IllegalStateException("No ResultSet returned executeQuery($sql) on $this") } } -} \ No newline at end of file +} + + + +/** + * Perform a query on the connection using the [[StringTemplate]] to generate the SQL text + * and processes the result set with a function + */ +fun Connection.query(template : StringTemplate, resultBlock : (ResultSet) -> T) : T { + val preparedStatement = prepare(template) + return preparedStatement.query(resultBlock) +} + +/** + * Creates a [[PreparedStatement]] from the [[StringTemplate]] + */ +fun Connection.prepare(template : StringTemplate) : PreparedStatement { + val builder = PreparedStatementBuilder(template, this) + builder.bind() + return builder.statement +} + +class PreparedStatementBuilder(val template : StringTemplate, val connection : Connection) { + private var parameterIndex = 0 + + public val sql : String = createSql() + + public val statement: PreparedStatement = lookupOrCreateStatement() + + /** + * Binds the values in the [[StringTemplate]] to the [[PreparedStatement]] + */ + fun bind() { + var constantText = true + template.forEach{ + if (!constantText) { + expression(it) + } + constantText = !constantText + } + } + + fun expression(value : Any?) : Unit { + // TODO causes compiler error + // if (value is Number) { + if (value is Int) { + expression(value) + } else if (value is Double) { + expression(value) + } else if (value is Float) { + expression(value) + } else if (value is BigDecimal) { + expression(value) + } else if (value is Byte) { + expression(value) + } else if (value is Long) { + expression(value) + } else if (value is Short) { + expression(value) + /* + } else { + expression(value.toDouble()) + } + */ + } + else if (value is String) { + expression(value) + } else if (value is ByteArray) { + expression(value) + } else if (value is Date) { + expression(value) + } else if (value is Time) { + expression(value) + } else if (value is Timestamp) { + expression(value) + } else { + statement.setObject(nextParameterIndex(), value) + } + } + + fun expression(value : String?) : Unit { + statement.setString(nextParameterIndex(), value) + } + + fun expression(value : Int) : Unit { + statement.setInt(nextParameterIndex(), value) + } + + fun expression(value : BigDecimal?) : Unit { + statement.setBigDecimal(nextParameterIndex(), value) + } + + fun expression(value : Byte) : Unit { + statement.setByte(nextParameterIndex(), value) + } + + fun expression(value : Double) : Unit { + statement.setDouble(nextParameterIndex(), value) + } + + fun expression(value : Float) : Unit { + statement.setFloat(nextParameterIndex(), value) + } + + fun expression(value : Long) : Unit { + statement.setLong(nextParameterIndex(), value) + } + + fun expression(value : Short) : Unit { + statement.setShort(nextParameterIndex(), value) + } + + fun expression(value : ByteArray) : Unit { + statement.setBytes(nextParameterIndex(), value) + } + + fun expression(value : Date) : Unit { + statement.setDate(nextParameterIndex(), value) + } + + fun expression(value : Time) : Unit { + statement.setTime(nextParameterIndex(), value) + } + + fun expression(value : Timestamp) : Unit { + statement.setTimestamp(nextParameterIndex(), value) + } + + // TODO bind other kinds! + + /** + * Looks up the [[PreparedStatement]] in a cache or creates a new one + */ + protected fun lookupOrCreateStatement(): PreparedStatement { + val answer = connection.prepareStatement(sql) + if (answer == null) { + throw IllegalStateException("No PreparedStatement returned from $connection") + } else { + return answer + } + } + + protected fun nextParameterIndex() : Int = ++parameterIndex + + protected fun createSql() : String { + val out = StringBuilder() + var constantText = true + template.forEach { + out.append(if (constantText) it else "?") + constantText = !constantText + } + return out.toString() ?: "" + } +} + diff --git a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/DataSources.kt b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/DataSources.kt index fbbe43c2591..8925868a591 100644 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/DataSources.kt +++ b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/DataSources.kt @@ -2,6 +2,7 @@ package kotlin.jdbc import java.sql.* import javax.sql.* +import kotlin.template.StringTemplate /** * Processes a connection from the pool using the given function block @@ -38,4 +39,18 @@ fun DataSource.update(sql: String): Int { */ fun DataSource.query(sql: String, block: (ResultSet) -> T): T { return use{ it.query(sql, block) } -} \ No newline at end of file +} + +/** + * Performs the update using the given SQL using a [[StringTemplate]] + */ +fun DataSource.update(template : StringTemplate) : Int { + return use{ it.update(template) } +} + +/** + * Perform a query on the connection using the SQL from the [[StringTemplate]] and processes the result set with a function + */ +fun DataSource.query(template : StringTemplate, resultBlock : (ResultSet) -> T) : T { + return use{ it.query(template, resultBlock) } +} diff --git a/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTemplateTest.kt b/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTemplateTest.kt index 41d2e2c90be..95a55bce513 100644 --- a/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTemplateTest.kt +++ b/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTemplateTest.kt @@ -10,175 +10,7 @@ import test.kotlin.jdbc. * import junit.framework.TestCase import javax.sql.DataSource -import java.sql.Connection -import java.sql.PreparedStatement -import java.sql.ResultSet -import java.math.BigDecimal -import java.sql.Date -import java.sql.Time -import java.sql.Timestamp - -fun DataSource.update(template : StringTemplate) : Int { - return use{ it.update(template) } -} - -fun DataSource.query(template : StringTemplate, resultBlock : (ResultSet) -> T) : T { - return use{ it.query(template, resultBlock) } -} - -fun Connection.update(template : StringTemplate) : Int { - val preparedStatement = prepare(template) - return preparedStatement.update() -} - - -fun Connection.query(template : StringTemplate, resultBlock : (ResultSet) -> T) : T { - val preparedStatement = prepare(template) - return preparedStatement.query(resultBlock) -} - -fun Connection.prepare(template : StringTemplate) : PreparedStatement { - val builder = PreparedStatementBuilder(template, this) - builder.bind() - return builder.statement -} - -trait Binding { - fun bind(statement : PreparedStatement) : Unit -} - -class PreparedStatementBuilder(val template : StringTemplate, val connection : Connection) { - private var parameterIndex = 0 - - public val sql : String = createSql() - - public val statement: PreparedStatement = lookupOrCreateStatement() - - /** - * Binds the values in the [[StringTemplate]] to the [[PreparedStatement]] - */ - fun bind() { - var constantText = true - template.forEach{ - if (!constantText) { - expression(it) - } - constantText = !constantText - } - } - - fun expression(value : Any?) : Unit { - // TODO causes compiler error - // if (value is Number) { - if (value is Int) { - expression(value) - } else if (value is Double) { - expression(value) - } else if (value is Float) { - expression(value) - } else if (value is BigDecimal) { - expression(value) - } else if (value is Byte) { - expression(value) - } else if (value is Long) { - expression(value) - } else if (value is Short) { - expression(value) - /* - } else { - expression(value.toDouble()) - } - */ - } - else if (value is String) { - expression(value) - } else if (value is ByteArray) { - expression(value) - } else if (value is Date) { - expression(value) - } else if (value is Time) { - expression(value) - } else if (value is Timestamp) { - expression(value) - } else { - statement.setObject(nextParameterIndex(), value) - } - } - - fun expression(value : String?) : Unit { - statement.setString(nextParameterIndex(), value) - } - - fun expression(value : Int) : Unit { - statement.setInt(nextParameterIndex(), value) - } - - fun expression(value : BigDecimal?) : Unit { - statement.setBigDecimal(nextParameterIndex(), value) - } - - fun expression(value : Byte) : Unit { - statement.setByte(nextParameterIndex(), value) - } - - fun expression(value : Double) : Unit { - statement.setDouble(nextParameterIndex(), value) - } - - fun expression(value : Float) : Unit { - statement.setFloat(nextParameterIndex(), value) - } - - fun expression(value : Long) : Unit { - statement.setLong(nextParameterIndex(), value) - } - - fun expression(value : Short) : Unit { - statement.setShort(nextParameterIndex(), value) - } - - fun expression(value : ByteArray) : Unit { - statement.setBytes(nextParameterIndex(), value) - } - - fun expression(value : Date) : Unit { - statement.setDate(nextParameterIndex(), value) - } - - fun expression(value : Time) : Unit { - statement.setTime(nextParameterIndex(), value) - } - - fun expression(value : Timestamp) : Unit { - statement.setTimestamp(nextParameterIndex(), value) - } - - // TODO bind other kinds! - - /** - * Looks up the [[PreparedStatement]] in a cache or creates a new one - */ - protected fun lookupOrCreateStatement(): PreparedStatement { - val answer = connection.prepareStatement(sql) - if (answer == null) { - throw IllegalStateException("No PreparedStatement returned from $connection") - } else { - return answer - } - } - - protected fun nextParameterIndex() : Int = ++parameterIndex - - protected fun createSql() : String { - val out = StringBuilder() - var constantText = true - template.forEach { - out.append(if (constantText) it else "?") - constantText = !constantText - } - return out.toString() ?: "" - } -} +import java.sql. * class JdbcTemplateTest : TestCase() { diff --git a/libraries/website/src/test/kotlin/org/jetbrains/kotlin/site/GenerateSiteTest.kt b/libraries/website/src/test/kotlin/org/jetbrains/kotlin/site/GenerateSiteTest.kt index 43c92de1827..7114f548b2e 100644 --- a/libraries/website/src/test/kotlin/org/jetbrains/kotlin/site/GenerateSiteTest.kt +++ b/libraries/website/src/test/kotlin/org/jetbrains/kotlin/site/GenerateSiteTest.kt @@ -32,6 +32,10 @@ class GenerateSiteTest : TestCase() { config.title = "Kotlin API ($version)" config.version = version config.ignorePackages.add("org.jetbrains.kotlin") + config.ignorePackages.add("java") + config.ignorePackages.add("jet") + config.ignorePackages.add("junit") + config.ignorePackages.add("sun") val compiler = KDocCompiler() compiler.exec(System.out, args)