diff --git a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt index 2ebcac9..1bd52d6 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt @@ -6,7 +6,6 @@ import com.github.jasync.sql.db.QueryResult 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 com.github.jasync.sql.db.util.length import fr.postgresjson.entity.EntityI import fr.postgresjson.serializer.Serializer import fr.postgresjson.utils.LoggerDelegate @@ -17,17 +16,6 @@ typealias SelectOneCallback = QueryResult.(T?) -> Unit typealias SelectCallback = QueryResult.(List) -> Unit typealias SelectPaginatedCallback = QueryResult.(Paginated) -> Unit -interface Executable { - fun > select(sql: String, typeReference: TypeReference, values: List = emptyList(), block: SelectOneCallback = {}): R? - fun > select(sql: String, typeReference: TypeReference, values: Map, block: SelectOneCallback = {}): R? - fun > select(sql: String, typeReference: TypeReference>, values: List = emptyList(), block: SelectCallback = {}): List - fun > select(sql: String, typeReference: TypeReference>, values: Map, block: SelectCallback = {}): List - fun > select(sql: String, page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: SelectPaginatedCallback = {}): Paginated - fun exec(sql: String, values: List = emptyList()): QueryResult - fun exec(sql: String, values: Map): QueryResult - fun sendQuery(sql: String): QueryResult -} - class Connection( private val database: String, private val username: String, @@ -210,20 +198,3 @@ class Connection( } } - -data class Paginated>( - val result: List, - val offset: Int, - val limit: Int, - val total: Int -) { - val currentPage: Int = (offset / limit) + 1 - val count: Int = result.length - - init { - if (offset < 0) error("offset must be greather or equal than 0") - if (limit < 1) error("limit must be greather than 1") - if (total < 1) error("total must be greather or equal than 0") - } -} - diff --git a/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt new file mode 100644 index 0000000..773c72e --- /dev/null +++ b/src/main/kotlin/fr/postgresjson/connexion/EmbedExecutable.kt @@ -0,0 +1,21 @@ +package fr.postgresjson.connexion + +import com.fasterxml.jackson.core.type.TypeReference +import com.github.jasync.sql.db.QueryResult +import fr.postgresjson.entity.EntityI + +interface EmbedExecutable { + val connection: Connection + override fun toString(): String + + fun > select(typeReference: TypeReference, values: List = emptyList(), block: SelectOneCallback = {}): R? + fun > select(typeReference: TypeReference, values: Map, block: SelectOneCallback = {}): R? + + fun > select(typeReference: TypeReference>, values: List = emptyList(), block: SelectCallback = {}): List + fun > select(typeReference: TypeReference>, values: Map, block: SelectCallback = {}): List + + fun > select(page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: SelectPaginatedCallback = {}): Paginated + + fun exec(values: List = emptyList()): QueryResult + fun exec(values: Map): QueryResult +} \ No newline at end of file diff --git a/src/main/kotlin/fr/postgresjson/connexion/Executable.kt b/src/main/kotlin/fr/postgresjson/connexion/Executable.kt new file mode 100644 index 0000000..7cb599b --- /dev/null +++ b/src/main/kotlin/fr/postgresjson/connexion/Executable.kt @@ -0,0 +1,16 @@ +package fr.postgresjson.connexion + +import com.fasterxml.jackson.core.type.TypeReference +import com.github.jasync.sql.db.QueryResult +import fr.postgresjson.entity.EntityI + +interface Executable { + fun > select(sql: String, typeReference: TypeReference, values: List = emptyList(), block: SelectOneCallback = {}): R? + fun > select(sql: String, typeReference: TypeReference, values: Map, block: SelectOneCallback = {}): R? + fun > select(sql: String, typeReference: TypeReference>, values: List = emptyList(), block: SelectCallback = {}): List + fun > select(sql: String, typeReference: TypeReference>, values: Map, block: SelectCallback = {}): List + fun > select(sql: String, page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: SelectPaginatedCallback = {}): Paginated + fun exec(sql: String, values: List = emptyList()): QueryResult + fun exec(sql: String, values: Map): QueryResult + fun sendQuery(sql: String): QueryResult +} \ No newline at end of file diff --git a/src/main/kotlin/fr/postgresjson/connexion/Function.kt b/src/main/kotlin/fr/postgresjson/connexion/Function.kt new file mode 100644 index 0000000..ac2c095 --- /dev/null +++ b/src/main/kotlin/fr/postgresjson/connexion/Function.kt @@ -0,0 +1,119 @@ +package fr.postgresjson.connexion + +import com.fasterxml.jackson.core.type.TypeReference +import com.github.jasync.sql.db.QueryResult +import fr.postgresjson.definition.Function +import fr.postgresjson.entity.EntityI + +class Function(val definition: Function, override val connection: Connection): EmbedExecutable { + override fun toString(): String { + return definition.name + } + + /** + * Select One entity with list of parameters + */ + override fun > select(typeReference: TypeReference, values: List, block: (QueryResult, R?) -> Unit): R? { + val args = compileArgs(values) + val sql = "SELECT * FROM ${definition.name} ($args)" + + return connection.select(sql, typeReference, values, block) + } + + inline fun > selectOne(values: List = emptyList(), noinline block: SelectOneCallback = {}): R? = + select(object: TypeReference() {}, values, block) + + /** + * Select One entity with named parameters + */ + override fun > select(typeReference: TypeReference, values: Map, block: (QueryResult, R?) -> Unit): R? { + val args = compileArgs(values) + val sql = "SELECT * FROM ${definition.name} ($args)" + + return connection.select(sql, typeReference, values, block) + } + + inline fun > selectOne(values: Map, noinline block: SelectOneCallback = {}): R? = + select(object: TypeReference() {}, values, block) + + /** + * Select list of entities with list of parameters + */ + override fun > select(typeReference: TypeReference>, values: List, block: (QueryResult, List) -> Unit): List { + val args = compileArgs(values) + val sql = "SELECT * FROM ${definition.name} ($args)" + + return connection.select(sql, typeReference, values, block) + } + + inline fun > select(values: List = emptyList(), noinline block: SelectCallback = {}): List = + select(object: TypeReference>() {}, values, block) + + /** + * Select list of entities with named parameters + */ + override fun > select(typeReference: TypeReference>, values: Map, block: (QueryResult, List) -> Unit): List { + val args = compileArgs(values) + val sql = "SELECT * FROM ${definition.name} ($args)" + + return connection.select(sql, typeReference, values, block) + } + + inline fun > select(values: Map, noinline block: SelectCallback = {}): List = + select(object: TypeReference>() {}, values, block) + + override fun > select(page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: (QueryResult, Paginated) -> Unit): Paginated { + val offset = (page - 1) * limit + val newValues = values + .plus("offset" to offset) + .plus("limit" to limit) + + val args = compileArgs(newValues) + val sql = "SELECT * FROM ${definition.name} ($args)" + + return connection.select(sql, page, limit, typeReference, values, block) + } + inline fun > select(page: Int, limit: Int, values: Map = emptyMap(), noinline block: SelectPaginatedCallback = {}): Paginated = + select(page, limit, object: TypeReference>() {}, values, block) + + override fun exec(values: List): QueryResult { + val args = compileArgs(values) + val sql = "SELECT * FROM ${definition.name} ($args)" + + return connection.exec(sql, values) + } + + override fun exec(values: Map): QueryResult { + val args = compileArgs(values) + val sql = "SELECT * FROM ${definition.name} ($args)" + + return connection.exec(sql, values) + } + + private fun compileArgs(values: List): String { + val placeholders = values + .filterIndexed { index, any -> + definition.parameters[index].default === null || any !== null + } + .mapIndexed { index, any -> + "?::" + definition.parameters[index].type + } + + return placeholders.joinToString(separator = ", ") + } + + private fun compileArgs(values: Map): String { + val parameters = definition.getParametersIndexedByName() + val placeholders = values + .filter { entry -> + val parameter = parameters[entry.key] ?: error("Parameter ${entry.key} not exist") + parameter.default === null || entry.value !== null + } + .map { entry -> + val parameter = parameters[entry.key]!! + """"${parameter.name}" := :${parameter.name}::${parameter.type}""" + } + + return placeholders.joinToString(separator = ", ") + } +} \ No newline at end of file diff --git a/src/main/kotlin/fr/postgresjson/connexion/Paginated.kt b/src/main/kotlin/fr/postgresjson/connexion/Paginated.kt new file mode 100644 index 0000000..12c9dc6 --- /dev/null +++ b/src/main/kotlin/fr/postgresjson/connexion/Paginated.kt @@ -0,0 +1,20 @@ +package fr.postgresjson.connexion + +import com.github.jasync.sql.db.util.length +import fr.postgresjson.entity.EntityI + +data class Paginated>( + val result: List, + val offset: Int, + val limit: Int, + val total: Int +) { + val currentPage: Int = (offset / limit) + 1 + val count: Int = result.length + + init { + if (offset < 0) error("offset must be greather or equal than 0") + if (limit < 1) error("limit must be greather than 1") + if (total < 1) error("total must be greather or equal than 0") + } +} \ No newline at end of file diff --git a/src/main/kotlin/fr/postgresjson/connexion/Query.kt b/src/main/kotlin/fr/postgresjson/connexion/Query.kt new file mode 100644 index 0000000..5a35ad4 --- /dev/null +++ b/src/main/kotlin/fr/postgresjson/connexion/Query.kt @@ -0,0 +1,54 @@ +package fr.postgresjson.connexion + +import com.fasterxml.jackson.core.type.TypeReference +import com.github.jasync.sql.db.QueryResult +import fr.postgresjson.entity.EntityI + + +class Query(private val sql: String, override val connection: Connection): EmbedExecutable { + override fun toString(): String { + return sql + } + + override fun > select(typeReference: TypeReference, values: List, block: (QueryResult, R?) -> Unit): R? { + return connection.select(this.toString(), typeReference, values, block) + } + + inline fun > selectOne(values: List = emptyList(), noinline block: SelectOneCallback = {}): R? = + select(object: TypeReference() {}, values, block) + + override fun > select(typeReference: TypeReference, values: Map, block: (QueryResult, R?) -> Unit): R? { + return connection.select(this.toString(), typeReference, values, block) + } + + inline fun > selectOne(values: Map, noinline block: SelectOneCallback = {}): R? = + select(object: TypeReference() {}, values, block) + + override fun > select(typeReference: TypeReference>, values: List, block: (QueryResult, List) -> Unit): List { + return connection.select(this.toString(), typeReference, values, block) + } + + inline fun > select(values: List = emptyList(), noinline block: SelectCallback = {}): List = + select(object: TypeReference>() {}, values, block) + + override fun > select(typeReference: TypeReference>, values: Map, block: (QueryResult, List) -> Unit): List { + return connection.select(this.toString(), typeReference, values, block) + } + + inline fun > select(values: Map, noinline block: SelectCallback = {}): List = + select(object: TypeReference>() {}, values, block) + + override fun > select(page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: (QueryResult, Paginated) -> Unit): Paginated { + return connection.select(this.toString(), page, limit, typeReference, values, block) + } + inline fun > select(page: Int, limit: Int, values: Map = emptyMap(), noinline block: SelectPaginatedCallback = {}): Paginated = + select(page, limit, object: TypeReference>() {}, values, block) + + override fun exec(values: List): QueryResult { + return connection.exec(sql, values) + } + + override fun exec(values: Map): QueryResult { + return connection.exec(sql, values) + } +} \ No newline at end of file diff --git a/src/main/kotlin/fr/postgresjson/connexion/Requester.kt b/src/main/kotlin/fr/postgresjson/connexion/Requester.kt index 7ff62aa..8ce672f 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Requester.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Requester.kt @@ -1,8 +1,5 @@ package fr.postgresjson.connexion -import com.fasterxml.jackson.core.type.TypeReference -import com.github.jasync.sql.db.QueryResult -import fr.postgresjson.entity.EntityI import java.io.File import fr.postgresjson.definition.Function as DefinitionFunction @@ -73,183 +70,6 @@ class Requester( return queries[path]!! } - class Query(private val sql: String, override val connection: Connection): Executable { - override fun toString(): String { - return sql - } - - override fun > select(typeReference: TypeReference, values: List, block: (QueryResult, R?) -> Unit): R? { - return connection.select(this.toString(), typeReference, values, block) - } - - inline fun > selectOne(values: List = emptyList(), noinline block: SelectOneCallback = {}): R? = - select(object: TypeReference() {}, values, block) - - override fun > select(typeReference: TypeReference, values: Map, block: (QueryResult, R?) -> Unit): R? { - return connection.select(this.toString(), typeReference, values, block) - } - - inline fun > selectOne(values: Map, noinline block: SelectOneCallback = {}): R? = - select(object: TypeReference() {}, values, block) - - override fun > select(typeReference: TypeReference>, values: List, block: (QueryResult, List) -> Unit): List { - return connection.select(this.toString(), typeReference, values, block) - } - - inline fun > select(values: List = emptyList(), noinline block: SelectCallback = {}): List = - select(object: TypeReference>() {}, values, block) - - override fun > select(typeReference: TypeReference>, values: Map, block: (QueryResult, List) -> Unit): List { - return connection.select(this.toString(), typeReference, values, block) - } - - inline fun > select(values: Map, noinline block: SelectCallback = {}): List = - select(object: TypeReference>() {}, values, block) - - override fun > select(page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: (QueryResult, Paginated) -> Unit): Paginated { - return connection.select(this.toString(), page, limit, typeReference, values, block) - } - inline fun > select(page: Int, limit: Int, values: Map = emptyMap(), noinline block: SelectPaginatedCallback = {}): Paginated = - select(page, limit, object: TypeReference>() {}, values, block) - - override fun exec(values: List): QueryResult { - return connection.exec(sql, values) - } - - override fun exec(values: Map): QueryResult { - return connection.exec(sql, values) - } - } - - class Function(val definition: DefinitionFunction, override val connection: Connection): Executable { - override fun toString(): String { - return definition.name - } - - /** - * Select One entity with list of parameters - */ - override fun > select(typeReference: TypeReference, values: List, block: (QueryResult, R?) -> Unit): R? { - val args = compileArgs(values) - val sql = "SELECT * FROM ${definition.name} ($args)" - - return connection.select(sql, typeReference, values, block) - } - - inline fun > selectOne(values: List = emptyList(), noinline block: SelectOneCallback = {}): R? = - select(object: TypeReference() {}, values, block) - - /** - * Select One entity with named parameters - */ - override fun > select(typeReference: TypeReference, values: Map, block: (QueryResult, R?) -> Unit): R? { - val args = compileArgs(values) - val sql = "SELECT * FROM ${definition.name} ($args)" - - return connection.select(sql, typeReference, values, block) - } - - inline fun > selectOne(values: Map, noinline block: SelectOneCallback = {}): R? = - select(object: TypeReference() {}, values, block) - - /** - * Select list of entities with list of parameters - */ - override fun > select(typeReference: TypeReference>, values: List, block: (QueryResult, List) -> Unit): List { - val args = compileArgs(values) - val sql = "SELECT * FROM ${definition.name} ($args)" - - return connection.select(sql, typeReference, values, block) - } - - inline fun > select(values: List = emptyList(), noinline block: SelectCallback = {}): List = - select(object: TypeReference>() {}, values, block) - - /** - * Select list of entities with named parameters - */ - override fun > select(typeReference: TypeReference>, values: Map, block: (QueryResult, List) -> Unit): List { - val args = compileArgs(values) - val sql = "SELECT * FROM ${definition.name} ($args)" - - return connection.select(sql, typeReference, values, block) - } - - inline fun > select(values: Map, noinline block: SelectCallback = {}): List = - select(object: TypeReference>() {}, values, block) - - override fun > select(page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: (QueryResult, Paginated) -> Unit): Paginated { - val offset = (page - 1) * limit - val newValues = values - .plus("offset" to offset) - .plus("limit" to limit) - - val args = compileArgs(newValues) - val sql = "SELECT * FROM ${definition.name} ($args)" - - return connection.select(sql, page, limit, typeReference, values, block) - } - inline fun > select(page: Int, limit: Int, values: Map = emptyMap(), noinline block: SelectPaginatedCallback = {}): Paginated = - select(page, limit, object: TypeReference>() {}, values, block) - - override fun exec(values: List): QueryResult { - val args = compileArgs(values) - val sql = "SELECT * FROM ${definition.name} ($args)" - - return connection.exec(sql, values) - } - - override fun exec(values: Map): QueryResult { - val args = compileArgs(values) - val sql = "SELECT * FROM ${definition.name} ($args)" - - return connection.exec(sql, values) - } - - private fun compileArgs(values: List): String { - val placeholders = values - .filterIndexed { index, any -> - definition.parameters[index].default === null || any !== null - } - .mapIndexed { index, any -> - "?::" + definition.parameters[index].type - } - - return placeholders.joinToString(separator = ", ") - } - - private fun compileArgs(values: Map): String { - val parameters = definition.getParametersIndexedByName() - val placeholders = values - .filter { entry -> - val parameter = parameters[entry.key] ?: error("Parameter ${entry.key} not exist") - parameter.default === null || entry.value !== null - } - .map { entry -> - val parameter = parameters[entry.key]!! - """"${parameter.name}" := :${parameter.name}::${parameter.type}""" - } - - return placeholders.joinToString(separator = ", ") - } - } - - interface Executable { - val connection: Connection - override fun toString(): String - - fun > select(typeReference: TypeReference, values: List = emptyList(), block: SelectOneCallback = {}): R? - fun > select(typeReference: TypeReference, values: Map, block: SelectOneCallback = {}): R? - - fun > select(typeReference: TypeReference>, values: List = emptyList(), block: SelectCallback = {}): List - fun > select(typeReference: TypeReference>, values: Map, block: SelectCallback = {}): List - - fun > select(page: Int, limit: Int, typeReference: TypeReference>, values: Map, block: SelectPaginatedCallback = {}): Paginated - - fun exec(values: List = emptyList()): QueryResult - fun exec(values: Map): QueryResult - } - class RequesterFactory( private val host: String = "localhost", private val port: Int = 5432,