added a few experimental alternatives implementations of string templates for string/html/jdbc etc for KT-1565 seems there's a few ways we could do it...
This commit is contained in:
@@ -8,11 +8,7 @@ import java.sql.*
|
||||
fun <T> Connection.statement(block: (Statement) -> T): T {
|
||||
val statement = createStatement()
|
||||
if (statement != null) {
|
||||
try {
|
||||
return block(statement)
|
||||
} finally {
|
||||
statement.close()
|
||||
}
|
||||
return statement.use(block)
|
||||
} else {
|
||||
throw IllegalStateException("No Statement returned from $this")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package kotlin.jdbc
|
||||
|
||||
/**
|
||||
* Helper method to process a statement on this collection
|
||||
*/
|
||||
import java.sql.PreparedStatement
|
||||
import java.sql.ResultSet
|
||||
|
||||
fun PreparedStatement.update(): Int {
|
||||
try {
|
||||
return this.executeUpdate()
|
||||
} finally {
|
||||
close()
|
||||
}
|
||||
}
|
||||
fun <T> PreparedStatement.query(block: (ResultSet) -> T): T {
|
||||
try {
|
||||
val resultSet = this.executeQuery()
|
||||
if (resultSet == null) {
|
||||
throw IllegalStateException("No ResultSet returned from $this")
|
||||
} else {
|
||||
return block(resultSet)
|
||||
}
|
||||
} finally {
|
||||
close()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package kotlin.jdbc
|
||||
|
||||
/**
|
||||
* Helper method to process a statement on this collection
|
||||
*/
|
||||
import java.sql.Statement
|
||||
|
||||
/**
|
||||
* Uses the statement with the given block then closes the statement
|
||||
*/
|
||||
fun <T> Statement.use(block : (Statement) -> T) : T {
|
||||
try {
|
||||
return block(this)
|
||||
} finally {
|
||||
close()
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,38 @@
|
||||
package test.kotlin.jdbc
|
||||
|
||||
import kotlin.jdbc.*
|
||||
import kotlin.test.*
|
||||
import kotlin.jdbc. *
|
||||
import kotlin.test. *
|
||||
|
||||
import junit.framework.TestCase
|
||||
import org.h2.jdbcx.JdbcDataSource
|
||||
import javax.sql.DataSource
|
||||
import org.h2.jdbcx.JdbcConnectionPool
|
||||
|
||||
fun createDataSource(): DataSource {
|
||||
val pool = JdbcConnectionPool.create("jdbc:h2:mem:KotlinJdbcTest;DB_CLOSE_DELAY=-1", "user", "password")
|
||||
if (pool == null) {
|
||||
val dataSource = createDataSource()
|
||||
|
||||
fun createDataSource() : DataSource {
|
||||
val dataSource = JdbcConnectionPool.create("jdbc:h2:mem:KotlinJdbcTest;DB_CLOSE_DELAY=-1", "user", "password")
|
||||
if (dataSource == null) {
|
||||
throw IllegalStateException("No DataSource created")
|
||||
} else {
|
||||
return pool
|
||||
}
|
||||
}
|
||||
|
||||
class JdbcTest : TestCase() {
|
||||
val dataSource = createDataSource()
|
||||
|
||||
fun testDatabase() {
|
||||
dataSource.update("create table foo (id int primary key, name varchar(100))")
|
||||
assertEquals(1, dataSource.update("insert into foo (id, name) values (1, 'James')"))
|
||||
assertEquals(1, dataSource.update("insert into foo (id, name) values (2, 'Andrey')"))
|
||||
|
||||
// lets query using integer lookups
|
||||
return dataSource
|
||||
}
|
||||
}
|
||||
|
||||
class JdbcTest : TestCase() {
|
||||
fun testQueryWithIndexColumnAccess() {
|
||||
dataSource.query("select * from foo") {
|
||||
for (row in it) {
|
||||
println("id ${row[1]} and name: ${row[2]}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testQueryWithNamedColumnAccess() {
|
||||
// query using names
|
||||
dataSource.query("select * from foo") {
|
||||
for (row in it) {
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package test.kotlin.jdbc.experiment1
|
||||
|
||||
import kotlin.template.experiment1.*
|
||||
import kotlin.jdbc.*
|
||||
import kotlin.test.*
|
||||
import kotlin.util.arrayList
|
||||
|
||||
import junit.framework.TestCase
|
||||
import javax.sql.DataSource
|
||||
|
||||
import test.kotlin.jdbc.createDataSource
|
||||
import java.sql.Connection
|
||||
import java.sql.PreparedStatement
|
||||
import java.sql.ResultSet
|
||||
|
||||
fun DataSource.update(fn: (PreparedStatementBuilder) -> Unit): Int {
|
||||
return use{ it.update(fn) }
|
||||
}
|
||||
|
||||
fun <T> DataSource.query(fn: (PreparedStatementBuilder) -> Unit, resultBlock: (ResultSet) -> T): T {
|
||||
return use{ it.query(fn, resultBlock) }
|
||||
}
|
||||
|
||||
fun Connection.update(fn: (PreparedStatementBuilder) -> Unit): Int {
|
||||
val preparedStatement = prepare(fn)
|
||||
return preparedStatement.update()
|
||||
}
|
||||
|
||||
|
||||
fun <T> Connection.query(fn: (PreparedStatementBuilder) -> Unit, resultBlock: (ResultSet) -> T): T {
|
||||
val preparedStatement = prepare(fn)
|
||||
return preparedStatement.query(resultBlock)
|
||||
}
|
||||
|
||||
fun Connection.prepare(fn: (PreparedStatementBuilder) -> Unit): PreparedStatement {
|
||||
val builder = PreparedStatementBuilder(this)
|
||||
fn(builder)
|
||||
return builder.statement()
|
||||
}
|
||||
|
||||
trait Binding {
|
||||
fun bind(statement: PreparedStatement): Unit
|
||||
}
|
||||
class PreparedStatementBuilder(val connection: Connection) {
|
||||
val sql = StringBuilder()
|
||||
val tasks = arrayList<Binding>()
|
||||
private var parameterIndex = 0
|
||||
|
||||
fun text(value: String): Unit {
|
||||
// we assume all text is escaped already
|
||||
sql.append(value)
|
||||
}
|
||||
|
||||
fun expression(value: String): Unit {
|
||||
sql.append("?")
|
||||
tasks.add(object: Binding {
|
||||
override fun bind(statement : PreparedStatement) {
|
||||
statement.setString(nextParameterIndex(), value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TODO bind other kinds!
|
||||
|
||||
fun statement(): PreparedStatement {
|
||||
val answer = connection.prepareStatement(sql.toString())
|
||||
if (answer == null) {
|
||||
throw IllegalStateException("No PreparedStatement returned from $connection")
|
||||
} else {
|
||||
for (task in tasks) {
|
||||
task.bind(answer)
|
||||
}
|
||||
return answer
|
||||
}
|
||||
}
|
||||
|
||||
protected fun nextParameterIndex(): Int = ++parameterIndex
|
||||
}
|
||||
|
||||
|
||||
class JdbcTemplateTest : TestCase() {
|
||||
//val dataSource = createDataSource()
|
||||
|
||||
fun testTemplateInsert() {
|
||||
val id = 1
|
||||
|
||||
/*
|
||||
dataSource.update {
|
||||
it.text("select * from foo where id = ")
|
||||
it.expression(id)
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user