diff --git a/libraries/kotlin-jdbc/pom.xml b/libraries/kotlin-jdbc/pom.xml deleted file mode 100644 index dd755a81bcd..00000000000 --- a/libraries/kotlin-jdbc/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - 4.0.0 - - - org.jetbrains.kotlin - kotlin-project - 0.1-SNAPSHOT - - - kotlin-jdbc - - - - org.jetbrains.kotlin - kotlin-stdlib - ${project.version} - - - - com.h2database - h2 - 1.3.164 - test - - - - - src/main/kotlin - src/test/kotlin - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${project.version} - - - - compile - compile - - compile - - - - - test-compile - test-compile - - test-compile - - - - - - - diff --git a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Connections.kt b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Connections.kt deleted file mode 100644 index 5e784ee0cee..00000000000 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Connections.kt +++ /dev/null @@ -1,224 +0,0 @@ -package kotlin.jdbc - -import java.sql.* -import kotlin.template.StringTemplate -import java.math.BigDecimal -import java.util.Properties - -/** - * create connection for the specified jdbc url with no credentials - */ -fun getConnection(url : String) : Connection = DriverManager.getConnection(url) - -/** - * create connection for the specified jdbc url and properties - */ -fun getConnection(url : String, info : Map) : Connection = DriverManager.getConnection(url, info.toProperties()) - -/** - * create connection for the specified jdbc url and credentials - */ -fun getConnection(url : String, user : String, password : String) : Connection = DriverManager.getConnection(url, user, password) - -/** - * Executes specified block with connection and close connection after this - */ -fun Connection.use(block : (Connection) -> T) : T { - try { - return block(this) - } finally { - this.close() - } -} - -/** - * Helper method to process a statement on this connection - */ -fun Connection.statement(block: (Statement) -> T): T { - val statement = createStatement() - if (statement != null) { - return statement.use(block) - } else { - throw IllegalStateException("No Statement returned from $this") - } -} - -/** - * Perform an SQL update on the connection - */ -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 - */ -fun Connection.query(sql: String, block: (ResultSet) -> T): T { - return statement{ - val rs = it.executeQuery(sql) - block(rs) - } -} - - - -/** - * 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 deleted file mode 100644 index 5b3c9c8b41f..00000000000 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/DataSources.kt +++ /dev/null @@ -1,56 +0,0 @@ -package kotlin.jdbc - -import java.sql.* -import javax.sql.* -import kotlin.template.StringTemplate - -/** - * Processes a connection from the pool using the given function block - */ -fun DataSource.use(block : (Connection) -> T): T { - val connection = getConnection() - if (connection != null) { - try { - return block(connection) - } finally { - connection.close() - } - } else { - throw IllegalStateException("No Connection returned from $this") - } -} - -/** - * Helper method to process a statement on this collection - */ -fun DataSource.statement(block: (Statement) -> T): T { - return use { it.statement(block) } -} - -/** - * Perform an SQL update on the connection - */ -fun DataSource.update(sql: String): Int { - return use { it.update(sql) } -} - -/** - * Perform a query on the connection and processes the result set with a function - */ -fun DataSource.query(sql: String, block: (ResultSet) -> T): T { - return use { it.query(sql, block) } -} - -/** - * 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/main/kotlin/kotlin/jdbc/PreparedStatements.kt b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/PreparedStatements.kt deleted file mode 100644 index 4e3894804a2..00000000000 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/PreparedStatements.kt +++ /dev/null @@ -1,24 +0,0 @@ -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 PreparedStatement.query(block: (ResultSet) -> T): T { - try { - val resultSet = this.executeQuery() - return block(resultSet) - } finally { - close() - } -} \ No newline at end of file diff --git a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/ResultSets.kt b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/ResultSets.kt deleted file mode 100644 index f6210544e6d..00000000000 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/ResultSets.kt +++ /dev/null @@ -1,111 +0,0 @@ -package kotlin.jdbc - -import java.sql.* - -// Workaround for an import clash -import kotlin.Array - -/** - * Executes the specfied block with result set and then closes it - */ -public fun ResultSet.use(block : (ResultSet) -> R) : R { - try { - return block(this) - } finally { - this.close() - } -} - -/** -* Creates an iterator through a [[ResultSet]] -*/ -fun ResultSet.iterator() : Iterator { - val rs = this - return object : Iterator{ - public override fun hasNext() : Boolean = rs.next() - - public override fun next() : ResultSet = rs - } -} - -/** - * Returns iterable that calls to the specified mapper function for each row - */ -fun ResultSet.map(fn : (ResultSet) -> T) : Iterable { - val rs = this - - val iterator = object : Iterator{ - public override fun hasNext() : Boolean = rs.next() - - public override fun next() : T = fn(rs) - } - - return object : Iterable { - public override fun iterator(): Iterator = iterator - } -} - -/** - * Returns array with column names - */ -fun ResultSet.getColumnNames() : Array { - val meta = getMetaData() - return Array(meta.getColumnCount(), {meta.getColumnName(it + 1) ?: it.toString()}) -} - -/** - * Return array filled with values from current row in the cursor. Values will have the same order as column's order - * @columnNames you can specify column names to extract otherwise all columns will be extracted - */ -fun ResultSet.getValues(columnNames : Array = getColumnNames()) : Array { - return Array(columnNames.size(), { - this[columnNames[it]] - }) -} - -/** - * Return map filled with values from current row in the cursor. Uses column names as keys for result map. - * @param columnNames you can specify column names to extract otherwise all columns will be extracted - */ -fun ResultSet.getValuesAsMap(columnNames : Array = getColumnNames()) : Map { - val result = java.util.HashMap(columnNames.size()) - - columnNames.forEach { - result[it] = this[it] - } - - return result -} - -/** - * Returns the value at the given column index (starting at 1) - */ -fun ResultSet.get(columnId: Int): Any? = this.getObject(columnId) - -/** - * Returns the value at the given column name - */ -fun ResultSet.get(columnName: String): Any? = this.getObject(columnName) - -private fun ResultSet.ensureHasRow() : ResultSet { - if (!next()) { - throw IllegalStateException("There are no rows left in cursor") - } - return this -} - -/** - * Returns int value from the cursor at first column. May be useful to get result of count(*) - */ -fun ResultSet.singleInt() : Int = ensureHasRow().getInt(1) - -/** - * Returns long value from the cursor at first column. - */ -fun ResultSet.singleLong() : Long = ensureHasRow().getLong(1) - -/** - * Returns double value from the cursor at first column. - */ -fun ResultSet.singleDouble() : Double = ensureHasRow().getDouble(1) - diff --git a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Statements.kt b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Statements.kt deleted file mode 100644 index 72030555dab..00000000000 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/jdbc/Statements.kt +++ /dev/null @@ -1,17 +0,0 @@ -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 S.use(block : (S) -> T) : T { - try { - return block(this) - } finally { - close() - } -} diff --git a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/template/Templates.kt b/libraries/kotlin-jdbc/src/main/kotlin/kotlin/template/Templates.kt deleted file mode 100644 index bd72d30258d..00000000000 --- a/libraries/kotlin-jdbc/src/main/kotlin/kotlin/template/Templates.kt +++ /dev/null @@ -1,182 +0,0 @@ -package kotlin.template - -import kotlin.dom. * -import org.w3c.dom.Node -import java.util.Locale -import java.text.NumberFormat -import java.text.DateFormat -import java.util.Date - -@Deprecated("This class is part of an experimental implementation of string templates and is going to be removed") -public class StringTemplate(private val values: Array) { - - /** - * Converts the template into a String - */ - override fun toString(): String { - val out = StringBuilder() - forEach { out.append(it) } - return out.toString() - } - - /** - * Performs the given function on each value in the collection - */ - public fun forEach(fn: (Any?) -> Unit): Unit { - for (v in values) { - fn(v) - } - } -} - -/** - * Converts the string template into a string using the given formatter - * to encode values as Strings performing any special encoding (such as for HTML) - * or internationalisation. - * - * See [[HtmlFormatter] and [[LocaleFormatter] respectively. - */ -@Deprecated("This function is part of an experimental implementation of string templates and is going to be removed") -public fun StringTemplate.toString(formatter: Formatter): String { - val buffer = StringBuilder() - append(buffer, formatter) - return buffer.toString() -} - -/** - * Appends the text representation of this string template to the given output - * using the supplied formatter - */ -@Deprecated("This function is part of an experimental implementation of string templates and is going to be removed") -public fun StringTemplate.append(out: Appendable, formatter: Formatter): Unit { - var constantText = true - this.forEach { - if (constantText) { - if (it == null) { - throw IllegalStateException("No constant checks should be null"); - } else { - val text = it.toString() - out.append(text) - } - } else { - formatter.format(out, it) - } - constantText = !constantText - } -} - -/** - * Converts this string template to internationalised text using the supplied - * [[LocaleFormatter]] - */ -@Deprecated("This function is part of an experimental implementation of string templates and is going to be removed") -public fun StringTemplate.toLocale(formatter: LocaleFormatter = LocaleFormatter()): String = toString(formatter) - -/** - * Converts this string template to HTML text - */ -@Deprecated("This function is part of an experimental implementation of string templates and is going to be removed") -public fun StringTemplate.toHtml(formatter: HtmlFormatter = HtmlFormatter()): String = toString(formatter) - -/** - * Represents a formatter and encoder of values in a [[StringTemplate]] which understands - * how to format values for a particular [[Locale]] such as with the [[LocaleFormatter]] or - * to escape particular characters in different output formats such as [[HtmlFormatter] - */ -@Deprecated("This interface is part of an experimental implementation of string templates and is going to be removed") -public interface Formatter { - public fun format(buffer: Appendable, value: Any?): Unit -} - -/** - * Formats strings with no special encoding other than allowing the null text to be - * configured - */ -@Deprecated("This class is part of an experimental implementation of string templates and is going to be removed") -public open class ToStringFormatter : Formatter { - - private val nullString: String = "null" - - override fun toString(): String = "ToStringFormatter" - - public override fun format(out: Appendable, value: Any?) { - if (value == null) { - format(out, nullString) - } else if (value is StringTemplate) { - value.append(out, this) - } else { - format(out, value.toString()) - } - } - - /** - * Formats the given string allowing derived classes to override this method - * to escape strings with special characters such as for HTML - */ - public open fun format(out: Appendable, text: String): Unit { - out.append(text) - } -} - -@Deprecated("This property is part of an experimental implementation of string templates and is going to be removed") -public val defaultLocale: Locale = Locale.getDefault() - -/** - * Formats values using a given [[Locale]] for internationalisation - */ -@Deprecated("This class is part of an experimental implementation of string templates and is going to be removed") -public open class LocaleFormatter(protected val locale: Locale = defaultLocale) : ToStringFormatter() { - - override fun toString(): String = "LocaleFormatter{$locale}" - - public var numberFormat: NumberFormat = NumberFormat.getInstance(locale)!! - - public var dateFormat: DateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale)!! - - public override fun format(out: Appendable, value: Any?) { - if (value is Number) { - format(out, format(value)) - } else if (value is Date) { - format(out, format(value)) - } else { - super.format(out, value) - } - } - - public fun format(number: Number): String { - return numberFormat.format(number) ?: "" - } - - public fun format(date: Date): String { - return dateFormat.format(date) ?: "" - } -} - -/** - * Formats values for HTML encoding, escaping special characters in HTML. - */ -@Deprecated("This class is part of an experimental implementation of string templates and is going to be removed") -public class HtmlFormatter(locale: Locale = defaultLocale) : LocaleFormatter(locale) { - - override fun toString(): String = "HtmlFormatter{$locale}" - - public override fun format(out: Appendable, value: Any?) { - if (value is Node) { - out.append(value.toXmlString()) - } else { - super.format(out, value) - } - } - - public override fun format(buffer: Appendable, text: String): Unit { - for (c in text) { - if (c == '<') buffer.append("<") - else if (c == '>') buffer.append(">") - else if (c == '&') buffer.append("&") - else if (c == '"') buffer.append(""") - else buffer.append(c) - } - } -} - - 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 deleted file mode 100644 index ce211eca092..00000000000 --- a/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTemplateTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -package test.kotlin.jdbc.experiment1 - -import kotlin.jdbc.* -import kotlin.template.* -import kotlin.test.* -import org.junit.Test as test -import test.kotlin.jdbc.* - -class JdbcTemplateTest { - //val dataSource = createDataSource() - - @test fun templateInsert() { - val id = 3 - val name = "Stepan" - - // Mimicks the following code - // dataSource.update("insert into foo (id, name) values ($id, $name)") - - // TODO will use a tuple soon - dataSource.update( - StringTemplate(arrayOf("insert into foo (id, name) values (", id, ", ", name, ")")) - ) - - // Mimicks - // datasource.query("select * from foo where id = $id") { it.map{ it["name"] } } - - val names = dataSource.query( - StringTemplate(arrayOf("select * from foo where id = ", id)) - ) { - it.map{ it["name"] }.toList() - } - - println("Found names $names") - val actual = names.first() - assertEquals(name, actual) - } -} diff --git a/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTest.kt b/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTest.kt deleted file mode 100644 index 883260b0b7f..00000000000 --- a/libraries/kotlin-jdbc/src/test/kotlin/test/kotlin/jdbc/JdbcTest.kt +++ /dev/null @@ -1,95 +0,0 @@ -package test.kotlin.jdbc - -import java.sql.ResultSet -import javax.sql.DataSource -import kotlin.jdbc.* -import kotlin.test.* -import org.h2.jdbcx.JdbcConnectionPool -import org.junit.Test as test - -public val dataSource : 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 { - 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')")) - - return dataSource - } -} - -class JdbcTest { - @test fun queryWithIndexColumnAccess() { - dataSource.query("select * from foo") { - for (row in it) { - println("id ${row[1]} and name: ${row[2]}") - } - } - } - - @test fun queryWithNamedColumnAccess() { - // query using names - dataSource.query("select * from foo") { - for (row in it) { - println("name: ${row["name"]} has id ${row["id"]}") - } - } - } - - @test fun getValuesAsMap() { - dataSource.query("select * from foo") { - for (row in it) { - println(row.getValuesAsMap()) - } - } - } - - @test fun stringFormat() { - dataSource.query(kotlin.template.StringTemplate(arrayOf("select * from foo where id = ", 1))) { - for (row in it) { - println(row.getValuesAsMap()) - } - } - } - - @test fun mapIterator() { - val mapper = { rs: ResultSet -> - "id: ${rs["id"]}" - } - - dataSource.query("select * from foo") { - for (row in it.map(mapper)) { - println(row) - } - } - } - - @test fun map() { - dataSource.query("select * from foo") { - val rows = it.map { "id: ${it["id"]}" } - for (row in rows) { - println(row) - } - } - } - - @test fun count() { - dataSource.query("select count(*) from foo") { - println("count: ${it.singleInt()}") - } - } - - @test fun formatCursor() { - dataSource.query("select * from foo") { - println(it.getColumnNames().toList().joinToString("\t")) - - for (row in it) { - println(it.getValues().joinToString("\t")) - } - } - } -} diff --git a/libraries/pom.xml b/libraries/pom.xml index c9da886d8f4..ac138398668 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -97,7 +97,6 @@ tools/kotlin-js-tests-junit kunit - kotlin-jdbc examples/kotlin-java-example examples/js-example