package fr.postgresjson.connexion import com.fasterxml.jackson.core.type.TypeReference import com.github.jasync.sql.db.pool.ConnectionPool import com.github.jasync.sql.db.postgresql.PostgreSQLConnection import com.github.jasync.sql.db.postgresql.PostgreSQLConnectionBuilder import fr.postgresjson.Serializer import fr.postgresjson.entity.EntityI class Connection( private val database: String, private val username: String, private val password: String, private val host: String = "localhost", private val port: Int = 5432 ) { private lateinit var connection: ConnectionPool private val serializer = Serializer() fun connect(): ConnectionPool { if (!::connection.isInitialized || !connection.isConnected()) { connection = PostgreSQLConnectionBuilder.createConnectionPool( "jdbc:postgresql://$host:$port/$database?user=$username&password=$password" ) } return connection } fun ?> selectOne(sql: String, typeReference: TypeReference, values: List = emptyList()): R? { val future = connect().sendPreparedStatement(sql, compileArgs(values)) val json = future.get().rows[0].getString(0) return if (json === null) { null } else { serializer.deserialize(json, typeReference) } } inline fun ?> selectOne(sql: String, values: List = emptyList()): R? = selectOne(sql, object: TypeReference() {}, values) fun ?>> select(sql: String, typeReference: TypeReference, values: List = emptyList()): R { val future = connect().sendPreparedStatement(sql, compileArgs(values)) val json = future.get().rows[0].getString(0) return if (json === null) { listOf?>() as R } else { serializer.deserializeList(json, typeReference) } } inline fun ?>> select(sql: String, values: List = emptyList()): R = select(sql, object : TypeReference() {}, values) private fun compileArgs(values: List): List { return values.map { if (it is EntityI<*>) { serializer.serialize(it) } else { it } } } }