diff --git a/src/main/kotlin/fr/postgresjson/migration/Function.kt b/src/main/kotlin/fr/postgresjson/migration/Function.kt index 5efd2ec..8fe1193 100644 --- a/src/main/kotlin/fr/postgresjson/migration/Function.kt +++ b/src/main/kotlin/fr/postgresjson/migration/Function.kt @@ -37,7 +37,7 @@ data class Function( connection.sendQuery(up.script) this::class.java.classLoader.getResource("sql/migration/insertFunction.sql")!!.readText().let { - connection.selectOne(it, listOf(up))?.let { function -> + connection.selectOne(it, listOf(up.name, up.getDefinition(), up.script, down.script))?.let { function -> executedAt = function.executedAt doExecute = Action.OK } diff --git a/src/main/kotlin/fr/postgresjson/migration/Migrations.kt b/src/main/kotlin/fr/postgresjson/migration/Migrations.kt index 230dfb9..a799136 100644 --- a/src/main/kotlin/fr/postgresjson/migration/Migrations.kt +++ b/src/main/kotlin/fr/postgresjson/migration/Migrations.kt @@ -37,10 +37,12 @@ data class Migrations private constructor( private val queries: MutableMap = mutableMapOf(), private val functions: MutableMap = mutableMapOf() ) { - constructor(directory: File, connection: Connection): this(connection) { + constructor(directory: File, connection: Connection): this(listOf(directory), connection) + + constructor(directories: List, connection: Connection): this(connection) { initDB() getMigrationFromDB() - getMigrationFromDirectory(directory) + getMigrationFromDirectory(directories) queries.forEach { (_, query) -> if (query.doExecute === null) { query.doExecute = Action.DOWN @@ -75,6 +77,15 @@ data class Migrations private constructor( } } + /** + * Get all migration from multiples Directories + */ + private fun getMigrationFromDirectory(directory: List) { + directory.forEach { + getMigrationFromDirectory(it) + } + } + /** * Get all migration from Directory */ diff --git a/src/main/resources/sql/migration/createFunctionShema.sql b/src/main/resources/sql/migration/createFunctionShema.sql index 0495d68..1512815 100644 --- a/src/main/resources/sql/migration/createFunctionShema.sql +++ b/src/main/resources/sql/migration/createFunctionShema.sql @@ -9,5 +9,3 @@ CREATE TABLE IF NOT EXISTS migration.functions down text NOT NULL, version int NOT NULL ); - -CREATE SEQUENCE IF NOT EXISTS migration.version_seq; \ No newline at end of file diff --git a/src/main/resources/sql/migration/getNextVersion.sql b/src/main/resources/sql/migration/getNextVersion.sql deleted file mode 100644 index 904b21b..0000000 --- a/src/main/resources/sql/migration/getNextVersion.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT nextval('migration.version_seq'); \ No newline at end of file diff --git a/src/main/resources/sql/migration/insertFunction.sql b/src/main/resources/sql/migration/insertFunction.sql index 1c40057..6fa31d5 100644 --- a/src/main/resources/sql/migration/insertFunction.sql +++ b/src/main/resources/sql/migration/insertFunction.sql @@ -1,3 +1,7 @@ INSERT INTO migration.functions as f (filename, definition, executed_at, up, down, version) -VALUES (?, ?, now(), ?, ?, ?) +VALUES (?, ?, now(), ?, ?, ( + select coalesce(max(version), 0)+1 + from migration.functions f2 + where filename = f2.filename +)) RETURNING to_json(f); \ No newline at end of file diff --git a/src/main/resources/sql/migration/insertHistory.sql b/src/main/resources/sql/migration/insertHistory.sql index 98dd96d..0cb1d47 100644 --- a/src/main/resources/sql/migration/insertHistory.sql +++ b/src/main/resources/sql/migration/insertHistory.sql @@ -1,3 +1,7 @@ INSERT INTO migration.history as h (filename, executed_at, up, down, version) -VALUES (?, now(), ?, ?, nextval('migration.version_seq')) +VALUES (?, now(), ?, ?, ( + select coalesce(max(version), 0)+1 + from migration.history f2 + where filename = f2.filename +)) RETURNING to_json(h); diff --git a/src/test/kotlin/fr/postgresjson/MigrationTest.kt b/src/test/kotlin/fr/postgresjson/MigrationTest.kt index 7420f8e..cc4e4a1 100644 --- a/src/test/kotlin/fr/postgresjson/MigrationTest.kt +++ b/src/test/kotlin/fr/postgresjson/MigrationTest.kt @@ -1,11 +1,13 @@ package fr.postgresjson +import fr.postgresjson.connexion.Requester import fr.postgresjson.migration.Migration import fr.postgresjson.migration.Migrations import org.amshove.kluent.`should be equal to` import org.amshove.kluent.`should contain` import org.amshove.kluent.invoking import org.amshove.kluent.shouldThrow +import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import java.io.File @@ -32,6 +34,18 @@ class MigrationTest(): TestAbstract() { } shouldThrow Migrations.DownMigrationNotDefined::class } + @Test + fun `run forced down query`() { + val resources = File(this::class.java.getResource("/sql/migrations").toURI()) + val m = Migrations(resources, getConnextion()) + repeat(3) { + m.down(true).apply { + this `should contain` Pair("1", Migration.Status.OK) + size `should be equal to` 1 + } + } + } + @Test fun `run dry migrations`() { val resources = File(this::class.java.getResource("/sql/real_migrations").toURI()) @@ -76,4 +90,20 @@ class MigrationTest(): TestAbstract() { } } } + + @Test + fun `run functions migrations`() { + val resources = File(this::class.java.getResource("/sql/function").toURI()) + Migrations(resources, getConnextion()).apply { + run().size `should be equal to` 4 + } + + val objTest: RequesterTest.ObjTest? = Requester(getConnextion()) + .addFunction(resources) + .getFunction("test_function") + .selectOne(listOf("test", "plip")) + + Assertions.assertEquals(objTest!!.id, 3) + Assertions.assertEquals(objTest.name, "test") + } } \ No newline at end of file