fix function with same name

This commit is contained in:
2022-11-14 13:06:37 +01:00
parent 72a7aa7273
commit 9d28ea6f0d
6 changed files with 52 additions and 25 deletions

View File

@@ -97,7 +97,7 @@ class Function(val definition: Function, override val connection: Connection) :
}
private fun compileArgs(values: Map<String, Any?>): String {
val parameters = definition.getParametersIndexedByName()
val parameters = definition.parametersIndexedByName
val placeholders = values
.filter { entry ->
val parameter = parameters[entry.key] ?: parameters["_" + entry.key] ?: error("Parameter ${entry.key} of function ${definition.name} not exist")

View File

@@ -63,6 +63,11 @@ class Requester(
fun getQuery(path: String): Query = queries[path] ?: throw NoQueryDefined(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")
}

View File

@@ -1,5 +1,7 @@
package fr.postgresjson.definition
import fr.postgresjson.utils.Algorithm.MD5
import fr.postgresjson.utils.hash
import java.nio.file.Path
class Function(
@@ -48,22 +50,30 @@ class Function(
class FunctionNotFound(cause: Throwable? = null): Resource.ParseException("Function not found in script", cause)
fun getDefinition(): String {
val definition: String
get() {
return parameters
.filter { it.direction == Parameter.Direction.IN }
.joinToString(", ") { "${it.name} ${it.type}" }
.let { "$name ($it)" }
}
fun getParametersIndexedByName(): Map<String, Parameter> {
val definitionHash: String
get() {
return definition.hash(MD5)
}
val parametersIndexedByName: Map<String, Parameter>
get() {
return parameters.associateBy { it.name }
}
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 {
return other.script != this.script
}
}

View File

@@ -43,14 +43,14 @@ data class Function(
} catch (e: CompletionException) {
val cause = e.cause
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)
}
}
this::class.java.classLoader
.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 ->
executedAt = function.executedAt
doExecute = Action.OK

View File

@@ -133,17 +133,17 @@ class Migrations private constructor(
Throwable("The file $path was not found", cause)
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) {
val oldDefinition = functions[newDefinition.name]?.up ?: newDefinition
functions[newDefinition.name] = Function(newDefinition, oldDefinition, connection).apply {
val oldDefinition = functions[newDefinition.definitionHash]?.up ?: newDefinition
functions[newDefinition.definitionHash] = Function(newDefinition, oldDefinition, connection).apply {
doExecute = Action.UP
}
} else {
functions[newDefinition.name]?.doExecute = Action.OK
functions[newDefinition.definitionHash]?.doExecute = Action.OK
}
callback(functions[newDefinition.name]!!)
callback(functions[newDefinition.definitionHash]!!)
return this
}
@@ -215,7 +215,7 @@ class Migrations private constructor(
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()
migrationsScripts.forEach {
it.value.let { query ->

View 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')
}