Общие рекомендации
Обновление представлений, правил, хранимых процедур и т.д. объектов без состояния выполняется с помощью repeatable migrations.
Миграции строковых констант в коде (Flyway)
Миграции объектов без состояния бывает удобно хранить рядом с кодом, который их использует - например SQL-представление для Spring Data JDBC модели на чтение удобно хранить, в том же файле, что класс модели.
В Flyway такие миграции можно оформить только как Java-миграции, плюс для них необходимо в ручную вычислять чексумму, чтобы они исполнялись автоматически, при изменении значения константы.
Вычисление чексуммы, можно вынести в базовый класс:
open class BaseRepeatableMigration(
vararg migrationSqlStatements: String,
) : BaseJavaMigration() {
private val migrationSqlStatement = concatenateMigrations(migrationSqlStatements)
private fun concatenateMigrations(migrations: Array<out String>): String {
return migrations.joinToString(";")
}
override fun migrate(context: Context) {
val connection = context.connection
connection.prepareStatement(migrationSqlStatement).execute()
}
override fun getChecksum(): Int {
val bytes = migrationSqlStatement.toByteArray()
val crc32 = CRC32()
crc32.update(bytes)
return crc32.value.toInt()
}
}
После чего новые объекты без состояния можно будет добавлять так:
Файл миграции
package db.migration.devices
import project.domain.devices.firmwares.api.dtos.firmwaresViewDdl
import project.platform.migrations.BaseRepeatableMigration
class R__FirmwaresView : BaseRepeatableMigration(firmwaresViewDdl)
Файл DTO
const val firmwares = "firmwares_view"
@Language("PostgreSQL")
const val firmwaresViewDdl = """
DROP VIEW IF EXISTS $firmwares;
CREATE VIEW $firmwares AS (
SELECT
fi.id AS id,
fi.firmware_version AS firmware_version,
-- ...
FROM
firmware_infos fi
-- INNER JOIN ...
)
"""
@Table(firmwares)
data class Firmware(
@Id
val id: UUID,
// ...
)