Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ LABEL maintainer="Koudai Aono <koxudaxi@gmail.com>"
ENV MODULE_NAME local_data_api.main
ENV MARIADB_CLIENT_VERSION 2.5.0
ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk
ENV LD_LIBRARY_PATH /usr/lib/jvm/java-11-openjdk/jre/lib/amd64/server/
ENV LD_LIBRARY_PATH /usr/lib/jvm/java-17-openjdk/jre/lib/amd64/server/


# This app supports only single process to share connections on workers
ENV WEB_CONCURRENCY 1

RUN mkdir -p /usr/share/man/man1 \
&& apt-get update && apt-get install -y openjdk-11-jre libpq-dev \
&& apt-get update && apt-get install -y openjdk-17-jre libpq-dev \
&& savedAptMark="$(apt-mark showmanual)" \
&& apt-get install -y gcc curl \
&& pip install JPype1==1.2.0 psycopg2==2.8.5\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,15 @@ fun Application.module(testing: Boolean = false) {
val resultSet = statement.resultSet
val updatedCount = if (statement.updateCount < 0) 0 else statement.updateCount
val executeStatementResponse = if (resultSet is ResultSet) {
val values = statement.values
ExecuteStatementResponse(
updatedCount,
null,
statement.records,
if (request.includeResultMetadata) createColumnMetadata(resultSet) else null
if (request.formatRecordsAs == null || request.formatRecordsAs != "JSON")
createRecords(values) else null,
if (request.includeResultMetadata) createColumnMetadata(resultSet) else null,
if (request.formatRecordsAs != null && request.formatRecordsAs == "JSON")
createFormattedJson(createColumnMetadata(resultSet), values) else null
)
} else {
ExecuteStatementResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.koxudaxi.localDataApi

import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.*
import java.sql.*
import java.sql.Types.ARRAY
import java.time.OffsetDateTime
Expand Down Expand Up @@ -109,14 +111,14 @@ val Statement.updateResults: List<List<Field>>
}


val Statement.records: List<List<Field>>
val Statement.values: List<List<Any?>>
get() {
val records = mutableListOf<List<Field>>()
val records = mutableListOf<List<Any?>>()
while (resultSet.next()) {
this.resultSet.metaData.let { metaData ->
records.add(
IntRange(1, metaData.columnCount).map { index ->
createField(resultSet, index)
getFieldValue(resultSet, index)
}.toList()
)
}
Expand Down Expand Up @@ -148,6 +150,34 @@ fun createColumnMetadata(resultSet: ResultSet): List<ColumnMetadata> {
}


fun createRecords(values: List<List<Any?>>): List<List<Field>> {
return values.map { recordValues ->
recordValues.map { value ->
Field.fromValue(value)
}
}
}


fun createFormattedJson(columnMetadata: List<ColumnMetadata>, values: List<List<Any?>>): String {

val jsonObjects: MutableList<JsonObject> = mutableListOf()

values.forEach { recordValues ->
val recordMap = mutableMapOf<String, Any?>();
recordValues.forEachIndexed { index, recordValue ->
val columnLabel = columnMetadata[index].label
if (columnLabel != null) {
recordMap[columnLabel] = recordValue
}
}
jsonObjects.add(JsonObject(recordMap.toJsonObject()))
}

return Json.encodeToString(jsonObjects)
}


fun setup() {
val env = System.getenv()
val engine = env["ENGINE"] ?: "MySQL"
Expand Down
42 changes: 42 additions & 0 deletions kotlin/local-data-api/src/com/koxudaxi/localDataApi/Models.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.koxudaxi.localDataApi

import kotlinx.serialization.*
import kotlinx.serialization.json.*
import java.util.*


Expand Down Expand Up @@ -108,6 +109,7 @@ data class ExecuteStatementRequest(
val parameters: List<SqlParameter>? = null,
val schema: String? = null,
val transactionId: String? = null,
val formatRecordsAs: String? = null,
)


Expand Down Expand Up @@ -135,6 +137,7 @@ data class ExecuteStatementResponse(
val generatedFields: List<Field>? = null,
val records: List<List<Field>>? = null,
val columnMetadata: List<ColumnMetadata>? = null,
val formattedRecords: String? = null,
)

@Serializable
Expand Down Expand Up @@ -203,3 +206,42 @@ data class ErrorResponse(
val message: String?,
val code: String,
)


fun Any?.toJsonElement(): JsonElement {
return when (this) {
is Number -> JsonPrimitive(this)
is Boolean -> JsonPrimitive(this)
is String -> JsonPrimitive(this)
is Array<*> -> this.toJsonArray()
is List<*> -> this.toJsonArray()
is Map<*, *> -> this.toJsonObject()
is JsonElement -> this
else -> JsonNull
}
}


fun Array<*>.toJsonArray(): JsonArray {
val array = mutableListOf<JsonElement>()
this.forEach { array.add(it.toJsonElement()) }
return JsonArray(array)
}


fun List<*>.toJsonArray(): JsonArray {
val array = mutableListOf<JsonElement>()
this.forEach { array.add(it.toJsonElement()) }
return JsonArray(array)
}


fun Map<*, *>.toJsonObject(): JsonObject {
val map = mutableMapOf<String, JsonElement>()
this.forEach {
if (it.key is String) {
map[it.key as String] = it.value.toJsonElement()
}
}
return JsonObject(map)
}