fix function with same name
This commit is contained in:
@@ -97,7 +97,7 @@ class Function(val definition: Function, override val connection: Connection) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun compileArgs(values: Map<String, Any?>): String {
|
private fun compileArgs(values: Map<String, Any?>): String {
|
||||||
val parameters = definition.getParametersIndexedByName()
|
val parameters = definition.parametersIndexedByName
|
||||||
val placeholders = values
|
val placeholders = values
|
||||||
.filter { entry ->
|
.filter { entry ->
|
||||||
val parameter = parameters[entry.key] ?: parameters["_" + entry.key] ?: error("Parameter ${entry.key} of function ${definition.name} not exist")
|
val parameter = parameters[entry.key] ?: parameters["_" + entry.key] ?: error("Parameter ${entry.key} of function ${definition.name} not exist")
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ class Requester(
|
|||||||
private val queries: MutableMap<String, Query> = mutableMapOf(),
|
private val queries: MutableMap<String, Query> = mutableMapOf(),
|
||||||
private val functions: MutableMap<String, Function> = mutableMapOf()
|
private val functions: MutableMap<String, Function> = mutableMapOf()
|
||||||
) {
|
) {
|
||||||
constructor(connection: Connection) : this(connection, mutableMapOf(), mutableMapOf())
|
constructor(connection: Connection): this(connection, mutableMapOf(), mutableMapOf())
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
queriesDirectory: URI? = null,
|
queriesDirectory: URI? = null,
|
||||||
functionsDirectory: URI? = null
|
functionsDirectory: URI? = null
|
||||||
) : this(
|
): this(
|
||||||
connection = connection,
|
connection = connection,
|
||||||
queries = queriesDirectory?.toQuery(connection) ?: mutableMapOf(),
|
queries = queriesDirectory?.toQuery(connection) ?: mutableMapOf(),
|
||||||
functions = functionsDirectory?.toFunction(connection) ?: mutableMapOf(),
|
functions = functionsDirectory?.toFunction(connection) ?: mutableMapOf(),
|
||||||
@@ -63,6 +63,11 @@ class Requester(
|
|||||||
|
|
||||||
fun getQuery(path: String): Query = queries[path] ?: throw NoQueryDefined(path)
|
fun getQuery(path: String): Query = queries[path] ?: throw NoQueryDefined(path)
|
||||||
|
|
||||||
class NoFunctionDefined(name: String) : Exception("No function defined for $name")
|
|
||||||
class NoQueryDefined(path: String) : Exception("No query defined in $path")
|
fun <A> inTransaction(block: Requester.() -> A?): A? = connection.inTransaction {
|
||||||
|
this@Requester.block()
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoFunctionDefined(name: String): Exception("No function defined for $name")
|
||||||
|
class NoQueryDefined(path: String): Exception("No query defined in $path")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package fr.postgresjson.definition
|
package fr.postgresjson.definition
|
||||||
|
|
||||||
|
import fr.postgresjson.utils.Algorithm.MD5
|
||||||
|
import fr.postgresjson.utils.hash
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
class Function(
|
class Function(
|
||||||
override val script: String,
|
override val script: String,
|
||||||
override val source: Path? = null
|
override val source: Path? = null
|
||||||
) : Resource, ParametersInterface {
|
): Resource, ParametersInterface {
|
||||||
val returns: String
|
val returns: String
|
||||||
override val name: String
|
override val name: String
|
||||||
override val parameters: List<Parameter>
|
override val parameters: List<Parameter>
|
||||||
@@ -46,24 +48,32 @@ class Function(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FunctionNotFound(cause: Throwable? = null) : Resource.ParseException("Function not found in script", cause)
|
class FunctionNotFound(cause: Throwable? = null): Resource.ParseException("Function not found in script", cause)
|
||||||
|
|
||||||
fun getDefinition(): String {
|
val definition: String
|
||||||
return parameters
|
get() {
|
||||||
.filter { it.direction == Parameter.Direction.IN }
|
return parameters
|
||||||
.joinToString(", ") { "${it.name} ${it.type}" }
|
.filter { it.direction == Parameter.Direction.IN }
|
||||||
.let { "$name ($it)" }
|
.joinToString(", ") { "${it.name} ${it.type}" }
|
||||||
}
|
.let { "$name ($it)" }
|
||||||
|
}
|
||||||
|
|
||||||
fun getParametersIndexedByName(): Map<String, Parameter> {
|
val definitionHash: String
|
||||||
return parameters.associateBy { it.name }
|
get() {
|
||||||
}
|
return definition.hash(MD5)
|
||||||
|
}
|
||||||
|
|
||||||
|
val parametersIndexedByName: Map<String, Parameter>
|
||||||
|
get() {
|
||||||
|
return parameters.associateBy { it.name }
|
||||||
|
}
|
||||||
|
|
||||||
infix fun `has same definition`(other: Function): Boolean {
|
infix fun `has same definition`(other: Function): Boolean {
|
||||||
return other.getDefinition() == this.getDefinition()
|
return other.definition == this.definition
|
||||||
}
|
}
|
||||||
|
|
||||||
infix fun `is different from`(other: Function): Boolean {
|
infix fun `is different from`(other: Function): Boolean {
|
||||||
return other.script != this.script
|
return other.script != this.script
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,14 +43,14 @@ data class Function(
|
|||||||
} catch (e: CompletionException) {
|
} catch (e: CompletionException) {
|
||||||
val cause = e.cause
|
val cause = e.cause
|
||||||
if (cause is GenericDatabaseException && cause.errorMessage.fields['C'] == "42P13") {
|
if (cause is GenericDatabaseException && cause.errorMessage.fields['C'] == "42P13") {
|
||||||
connection.sendQuery("drop function ${down.getDefinition()}")
|
connection.sendQuery("drop function ${down.definition}")
|
||||||
connection.sendQuery(up.script)
|
connection.sendQuery(up.script)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this::class.java.classLoader
|
this::class.java.classLoader
|
||||||
.getResource("sql/migration/insertFunction.sql")!!.readText()
|
.getResource("sql/migration/insertFunction.sql")!!.readText()
|
||||||
.let { connection.selectOne<MigrationEntity>(it, listOf(up.name, up.getDefinition(), up.script, down.script)) }
|
.let { connection.selectOne<MigrationEntity>(it, listOf(up.name, up.definition, up.script, down.script)) }
|
||||||
?.let { function ->
|
?.let { function ->
|
||||||
executedAt = function.executedAt
|
executedAt = function.executedAt
|
||||||
doExecute = Action.OK
|
doExecute = Action.OK
|
||||||
|
|||||||
@@ -133,17 +133,17 @@ class Migrations private constructor(
|
|||||||
Throwable("The file $path was not found", cause)
|
Throwable("The file $path was not found", cause)
|
||||||
|
|
||||||
fun addFunction(newDefinition: DefinitionFunction, callback: (Function) -> Unit = {}): Migrations {
|
fun addFunction(newDefinition: DefinitionFunction, callback: (Function) -> Unit = {}): Migrations {
|
||||||
val currentFunction = functions[newDefinition.name]
|
val currentFunction = functions[newDefinition.definitionHash]
|
||||||
if (currentFunction === null || currentFunction `is different from` newDefinition) {
|
if (currentFunction === null || currentFunction `is different from` newDefinition) {
|
||||||
val oldDefinition = functions[newDefinition.name]?.up ?: newDefinition
|
val oldDefinition = functions[newDefinition.definitionHash]?.up ?: newDefinition
|
||||||
functions[newDefinition.name] = Function(newDefinition, oldDefinition, connection).apply {
|
functions[newDefinition.definitionHash] = Function(newDefinition, oldDefinition, connection).apply {
|
||||||
doExecute = Action.UP
|
doExecute = Action.UP
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
functions[newDefinition.name]?.doExecute = Action.OK
|
functions[newDefinition.definitionHash]?.doExecute = Action.OK
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(functions[newDefinition.name]!!)
|
callback(functions[newDefinition.definitionHash]!!)
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ class Migrations private constructor(
|
|||||||
return list.toMap()
|
return list.toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun down(force: Boolean = false): Map<String, Status> {
|
fun down(force: Boolean = false): Map<String, Status> {
|
||||||
val list: MutableMap<String, Status> = mutableMapOf()
|
val list: MutableMap<String, Status> = mutableMapOf()
|
||||||
migrationsScripts.forEach {
|
migrationsScripts.forEach {
|
||||||
it.value.let { query ->
|
it.value.let { query ->
|
||||||
|
|||||||
12
src/main/kotlin/fr/postgresjson/utils/md5.kt
Normal file
12
src/main/kotlin/fr/postgresjson/utils/md5.kt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package fr.postgresjson.utils
|
||||||
|
|
||||||
|
import java.math.BigInteger
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
internal enum class Algorithm(name: String) {
|
||||||
|
MD5("MD5")
|
||||||
|
}
|
||||||
|
internal fun String.hash(algorithm: Algorithm): String {
|
||||||
|
val md = MessageDigest.getInstance(algorithm.name)
|
||||||
|
return BigInteger(1, md.digest(toByteArray())).toString(16).padStart(32, '0')
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user