Compare commits
3 Commits
2.2.0
...
fix/functi
| Author | SHA1 | Date | |
|---|---|---|---|
| 551b860464 | |||
| 034e301073 | |||
| 9d28ea6f0d |
@@ -3,6 +3,20 @@
|
||||
## Gradle
|
||||
```kotlin
|
||||
// build.gradle.kts
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.github.flecomte:postgres-json:+")
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.flecomte:postgres-json:+")
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -63,6 +63,10 @@ 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")
|
||||
}
|
||||
|
||||
@@ -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,19 +50,26 @@ class Function(
|
||||
|
||||
class FunctionNotFound(cause: Throwable? = null) : Resource.ParseException("Function not found in script", cause)
|
||||
|
||||
fun getDefinition(): String {
|
||||
return parameters
|
||||
.filter { it.direction == Parameter.Direction.IN }
|
||||
.joinToString(", ") { "${it.name} ${it.type}" }
|
||||
.let { "$name ($it)" }
|
||||
}
|
||||
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> {
|
||||
return parameters.associateBy { it.name }
|
||||
}
|
||||
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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
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