summaryrefslogtreecommitdiff
path: root/common/src/main/kotlin/db/schema.kt
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/main/kotlin/db/schema.kt')
-rw-r--r--common/src/main/kotlin/db/schema.kt54
1 files changed, 41 insertions, 13 deletions
diff --git a/common/src/main/kotlin/db/schema.kt b/common/src/main/kotlin/db/schema.kt
index af589cbb..176c04ee 100644
--- a/common/src/main/kotlin/db/schema.kt
+++ b/common/src/main/kotlin/db/schema.kt
@@ -21,6 +21,8 @@ package tech.libeufin.common.db
import tech.libeufin.common.*
import org.postgresql.jdbc.PgConnection
+import org.postgresql.ds.PGSimpleDataSource
+import java.sql.Connection
import kotlin.io.path.Path
import kotlin.io.path.exists
import kotlin.io.path.readText
@@ -31,7 +33,7 @@ import kotlin.io.path.readText
* @param conn database connection
* @param cfg database configuration
*/
-fun maybeApplyV(conn: PgConnection, cfg: DatabaseConfig) {
+private fun maybeApplyV(conn: PgConnection, cfg: DatabaseConfig) {
conn.transaction {
val checkVSchema = conn.prepareStatement(
"SELECT schema_name FROM information_schema.schemata WHERE schema_name = '_v'"
@@ -44,32 +46,35 @@ fun maybeApplyV(conn: PgConnection, cfg: DatabaseConfig) {
}
}
+private fun migrationsPath(sqlFilePrefix: String): Sequence<String> = sequence {
+ for (n in 1..9999) {
+ val padded = n.toString().padStart(4, '0')
+ yield("$sqlFilePrefix-$padded")
+ }
+}
+
// sqlFilePrefix is, for example, "libeufin-bank" or "libeufin-nexus" (no trailing dash).
-fun initializeDatabaseTables(conn: PgConnection, cfg: DatabaseConfig, sqlFilePrefix: String) {
+private fun initializeDatabaseTables(conn: PgConnection, cfg: DatabaseConfig, sqlFilePrefix: String) {
logger.info("doing DB initialization, sqldir ${cfg.sqlDir}")
maybeApplyV(conn, cfg)
conn.transaction {
- val checkStmt = conn.prepareStatement("SELECT count(*) as n FROM _v.patches where patch_name = ?")
-
- for (n in 1..9999) {
- val numStr = n.toString().padStart(4, '0')
- val patchName = "$sqlFilePrefix-$numStr"
+ val checkStmt = conn.prepareStatement("SELECT EXISTS(SELECT FROM _v.patches where patch_name = ?)")
+ for (patchName in migrationsPath(sqlFilePrefix)) {
checkStmt.setString(1, patchName)
- val patchCount = checkStmt.oneOrNull { it.getInt(1) } ?: throw Exception("unable to query patches")
- if (patchCount >= 1) {
+ val applied = checkStmt.one { it.getBoolean(1) }
+ if (applied) {
logger.debug("patch $patchName already applied")
continue
}
- val path = Path("${cfg.sqlDir}/$sqlFilePrefix-$numStr.sql")
+ val path = Path("${cfg.sqlDir}/$patchName.sql")
if (!path.exists()) {
logger.debug("path $path doesn't exist anymore, stopping")
break
}
logger.info("applying patch $path")
- val sqlPatchText = path.readText()
- conn.execSQLUpdate(sqlPatchText)
+ conn.execSQLUpdate(path.readText())
}
val sqlProcedures = Path("${cfg.sqlDir}/$sqlFilePrefix-procedures.sql")
if (!sqlProcedures.exists()) {
@@ -81,9 +86,32 @@ fun initializeDatabaseTables(conn: PgConnection, cfg: DatabaseConfig, sqlFilePre
}
}
+internal fun checkMigrations(conn: Connection, cfg: DatabaseConfig, sqlFilePrefix: String) {
+ val checkStmt = conn.prepareStatement("SELECT EXISTS(SELECT FROM _v.patches where patch_name = ?)")
+
+ for (patchName in migrationsPath(sqlFilePrefix)) {
+ checkStmt.setString(1, patchName)
+ val path = Path("${cfg.sqlDir}/$patchName.sql")
+ if (!path.exists()) break
+ val applied = checkStmt.one { it.getBoolean(1) }
+ if (!applied) {
+ throw Exception("patch $patchName not applied, run '$sqlFilePrefix dbinit'")
+ }
+ }
+}
+
// sqlFilePrefix is, for example, "libeufin-bank" or "libeufin-nexus" (no trailing dash).
-fun resetDatabaseTables(conn: PgConnection, cfg: DatabaseConfig, sqlFilePrefix: String) {
+private fun resetDatabaseTables(conn: PgConnection, cfg: DatabaseConfig, sqlFilePrefix: String) {
logger.info("reset DB, sqldir ${cfg.sqlDir}")
val sqlDrop = Path("${cfg.sqlDir}/$sqlFilePrefix-drop.sql").readText()
conn.execSQLUpdate(sqlDrop)
+}
+
+fun PGSimpleDataSource.dbInit(cfg: DatabaseConfig, sqlFilePrefix: String, reset: Boolean) {
+ pgConnection().use { conn ->
+ if (reset) {
+ resetDatabaseTables(conn, cfg, sqlFilePrefix)
+ }
+ initializeDatabaseTables(conn, cfg, sqlFilePrefix)
+ }
} \ No newline at end of file