gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated (da2aa56e -> 117fa34b)


From: gnunet
Subject: [libeufin] branch master updated (da2aa56e -> 117fa34b)
Date: Mon, 11 Dec 2023 14:30:56 +0100

This is an automated email from the git hooks/post-receive script.

antoine pushed a change to branch master
in repository libeufin.

    from da2aa56e Drop leading + before POSTing to Telesign.
     new 303848df Reuse common unknown account error
     new 117fa34b Check postgres version and reuse connection when initialising 
database

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/kotlin/tech/libeufin/bank/Constants.kt    |  3 +
 .../main/kotlin/tech/libeufin/bank/CoreBankApi.kt  | 35 ++-------
 bank/src/main/kotlin/tech/libeufin/bank/Error.kt   | 33 +++++---
 bank/src/main/kotlin/tech/libeufin/bank/Main.kt    | 22 ++++--
 .../kotlin/tech/libeufin/bank/WireGatewayApi.kt    | 10 +--
 .../main/kotlin/tech/libeufin/bank/db/Database.kt  |  8 ++
 bank/src/main/kotlin/tech/libeufin/bank/helpers.kt |  5 +-
 bank/src/test/kotlin/helpers.kt                    |  6 +-
 .../src/main/kotlin/tech/libeufin/nexus/DbInit.kt  | 11 +--
 nexus/src/test/kotlin/Common.kt                    | 21 +++---
 util/src/main/kotlin/DB.kt                         | 87 +++++++++++-----------
 11 files changed, 123 insertions(+), 118 deletions(-)

diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
index 58969209..fca03215 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
@@ -38,6 +38,9 @@ val RESERVED_ACCOUNTS = setOf("admin", "bank")
 // Security
 const val MAX_BODY_LENGTH: Long = 4 * 1024 // 4kB
 
+// DB
+const val MIN_VERSION: Int = 15
+
 // API version
 const val COREBANK_API_VERSION: String = "2:1:2"
 const val CONVERSION_API_VERSION: String = "0:0:0"
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
index e5a87768..caac34b0 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/CoreBankApi.kt
@@ -245,10 +245,7 @@ private fun Routing.coreBankAccountsApi(db: Database, ctx: 
BankConfig) {
                 )
 
             when (db.account.delete(username)) {
-                AccountDeletionResult.UnknownAccount -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                AccountDeletionResult.UnknownAccount -> throw 
unknownAccount(username)
                 AccountDeletionResult.BalanceNotZero -> throw conflict(
                     "Account balance is not zero.",
                     TalerErrorCode.BANK_ACCOUNT_BALANCE_NOT_ZERO
@@ -262,10 +259,7 @@ private fun Routing.coreBankAccountsApi(db: Database, ctx: 
BankConfig) {
             val req = call.receive<AccountReconfiguration>()
             when (patchAccount(db, ctx, req, username, isAdmin)) {
                 AccountPatchResult.Success -> 
call.respond(HttpStatusCode.NoContent)
-                AccountPatchResult.UnknownAccount -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                AccountPatchResult.UnknownAccount -> throw 
unknownAccount(username)
                 AccountPatchResult.NonAdminName -> throw conflict(
                     "non-admin user cannot change their legal name",
                     TalerErrorCode.BANK_NON_ADMIN_PATCH_LEGAL_NAME
@@ -290,10 +284,7 @@ private fun Routing.coreBankAccountsApi(db: Database, ctx: 
BankConfig) {
             }
             when (db.account.reconfigPassword(username, req.new_password, 
req.old_password)) {
                 AccountPatchAuthResult.Success -> 
call.respond(HttpStatusCode.NoContent)
-                AccountPatchAuthResult.UnknownAccount -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                AccountPatchAuthResult.UnknownAccount -> throw 
unknownAccount(username)
                 AccountPatchAuthResult.OldPasswordMismatch -> throw conflict(
                     "old password does not match",
                     TalerErrorCode.BANK_PATCH_BAD_OLD_PASSWORD
@@ -323,10 +314,7 @@ private fun Routing.coreBankAccountsApi(db: Database, ctx: 
BankConfig) {
     }
     auth(db, TokenScope.readonly, allowAdmin = true) {
         get("/accounts/{USERNAME}") {
-            val account = db.account.get(username) ?: throw notFound(
-                "Account '$username' not found.",
-                TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-            )
+            val account = db.account.get(username) ?: throw 
unknownAccount(username)
             call.respond(account)
         }
     }
@@ -370,10 +358,7 @@ private fun Routing.coreBankTransactionsApi(db: Database, 
ctx: BankConfig) {
                 timestamp = Instant.now(),
             )
             when (res) {
-                is BankTransactionResult.UnknownDebtor -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                is BankTransactionResult.UnknownDebtor -> throw 
unknownAccount(username)
                 is BankTransactionResult.BothPartySame -> throw conflict(
                     "Wire transfer attempted with credit and debit party being 
the same bank account",
                     TalerErrorCode.BANK_SAME_ACCOUNT 
@@ -399,10 +384,7 @@ private fun Routing.coreBankWithdrawalApi(db: Database, 
ctx: BankConfig) {
             ctx.checkRegionalCurrency(req.amount)
             val opId = UUID.randomUUID()
             when (db.withdrawal.create(username, opId, req.amount)) {
-                WithdrawalCreationResult.UnknownAccount -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                WithdrawalCreationResult.UnknownAccount -> throw 
unknownAccount(username)
                 WithdrawalCreationResult.AccountIsExchange -> throw conflict(
                     "Exchange account cannot perform withdrawal operation",
                     TalerErrorCode.BANK_ACCOUNT_IS_EXCHANGE
@@ -543,10 +525,7 @@ private fun Routing.coreBankCashoutApi(db: Database, ctx: 
BankConfig) = conditio
                 validityPeriod = TAN_VALIDITY_PERIOD
             )
             when (res) {
-                is CashoutCreationResult.AccountNotFound -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                is CashoutCreationResult.AccountNotFound -> throw 
unknownAccount(username)
                 is CashoutCreationResult.BadConversion -> throw conflict(
                     "Wrong currency conversion",
                     TalerErrorCode.BANK_BAD_CONVERSION
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Error.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
index f8d930f6..68636fbb 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Error.kt
@@ -30,7 +30,7 @@ import tech.libeufin.util.*
  * and that is meant to be caught by Ktor and responded to the
  * client.
  */
-class LibeufinBankException(
+class LibeufinException(
     // Status code that Ktor will set for the response.
     val httpStatus: HttpStatusCode,
     // Error detail object, after Taler API.
@@ -61,7 +61,7 @@ suspend fun ApplicationCall.err(
     error: TalerErrorCode
 ) {
     err(
-        LibeufinBankException(
+        LibeufinException(
             httpStatus = status, talerError = TalerError(
                 code = error.code, err = error, hint = hint
             )
@@ -70,7 +70,7 @@ suspend fun ApplicationCall.err(
 }
 
 suspend fun ApplicationCall.err(
-    err: LibeufinBankException
+    err: LibeufinException
 ) {
     attributes.put(LOG_MSG, "${err.talerError.err.name} 
${err.talerError.hint}")
     respond(
@@ -85,40 +85,44 @@ fun libeufinError(
     hint: String?,
     error: TalerErrorCode,
     detail: String? = null
-): LibeufinBankException = LibeufinBankException(
+): LibeufinException = LibeufinException(
     httpStatus = status, talerError = TalerError(
         code = error.code, err = error, hint = hint, detail = detail
     )
 )
 
+/* ----- HTTP error ----- */
+
 fun forbidden(
     hint: String = "No rights on the resource",
     error: TalerErrorCode = TalerErrorCode.END
-): LibeufinBankException = libeufinError(HttpStatusCode.Forbidden, hint, error)
+): LibeufinException = libeufinError(HttpStatusCode.Forbidden, hint, error)
 
 fun unauthorized(
     hint: String,
     error: TalerErrorCode = TalerErrorCode.GENERIC_UNAUTHORIZED
-): LibeufinBankException = libeufinError(HttpStatusCode.Unauthorized, hint, 
error)
+): LibeufinException = libeufinError(HttpStatusCode.Unauthorized, hint, error)
 
-fun internalServerError(hint: String?): LibeufinBankException 
+fun internalServerError(hint: String?): LibeufinException 
     = libeufinError(HttpStatusCode.InternalServerError, hint, 
TalerErrorCode.GENERIC_INTERNAL_INVARIANT_FAILURE)
 
 fun notFound(
     hint: String,
     error: TalerErrorCode
-): LibeufinBankException = libeufinError(HttpStatusCode.NotFound, hint, error)
+): LibeufinException = libeufinError(HttpStatusCode.NotFound, hint, error)
 
 fun conflict(
     hint: String, error: TalerErrorCode
-): LibeufinBankException = libeufinError(HttpStatusCode.Conflict, hint, error)
+): LibeufinException = libeufinError(HttpStatusCode.Conflict, hint, error)
 
 fun badRequest(
     hint: String? = null, 
     error: TalerErrorCode = TalerErrorCode.GENERIC_JSON_INVALID,
     detail: String? = null
-): LibeufinBankException = libeufinError(HttpStatusCode.BadRequest, hint, 
error, detail)
+): LibeufinException = libeufinError(HttpStatusCode.BadRequest, hint, error, 
detail)
+
 
+/* ----- Currency checks ----- */
 
 fun BankConfig.checkRegionalCurrency(amount: TalerAmount) {
     if (amount.currency != regionalCurrency) throw badRequest(
@@ -132,4 +136,13 @@ fun BankConfig.checkFiatCurrency(amount: TalerAmount) {
         "Wrong currency: expected fiat currency $fiatCurrency got 
${amount.currency}",
         TalerErrorCode.GENERIC_CURRENCY_MISMATCH
     )
+}
+
+/* ----- Common errors ----- */
+
+fun unknownAccount(id: String): LibeufinException {
+    return notFound(
+        "Account '$id' not found",
+        TalerErrorCode.BANK_UNKNOWN_ACCOUNT
+    )
 }
\ No newline at end of file
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
index 8c0c1b08..5987fbcc 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Main.kt
@@ -141,7 +141,7 @@ fun Application.corebankWebApp(db: Database, ctx: 
BankConfig) {
     install(StatusPages) {
         exception<Exception> { call, cause ->
             when (cause) {
-                is LibeufinBankException -> call.err(cause)
+                is LibeufinException -> call.err(cause)
                 is SQLException -> {
                     when (cause.sqlState) {
                         PSQLState.SERIALIZATION_FAILURE.state -> call.err(
@@ -234,13 +234,15 @@ class BankDbInit : CliktCommand("Initialize the 
libeufin-bank database", name =
     override fun run() = cliCmd(logger){
         val config = talerConfig(common.config)
         val cfg = config.loadDbConfig()
-        if (requestReset) {
-            resetDatabaseTables(cfg, sqlFilePrefix = "libeufin-bank")
-        }
-        initializeDatabaseTables(cfg, sqlFilePrefix = "libeufin-bank")
         val ctx = config.loadBankConfig();
         val db = Database(cfg.dbConnStr, ctx.regionalCurrency, 
ctx.fiatCurrency)
         runBlocking {
+            db.conn { conn ->
+                if (requestReset) {
+                    resetDatabaseTables(conn, cfg, sqlFilePrefix = 
"libeufin-bank")
+                }
+                initializeDatabaseTables(conn, cfg, sqlFilePrefix = 
"libeufin-bank")
+            }
             // Create admin account if missing
             val res = maybeCreateAdminAccount(db, ctx) // logs provided by the 
helper
             when (res) {
@@ -302,7 +304,15 @@ class ServeBank : CliktCommand("Run libeufin-bank HTTP 
server", name = "serve")
             }
             module { corebankWebApp(db, ctx) }
         }
-        embeddedServer(Netty, env).start(wait = true)
+        val engine = embeddedServer(Netty, env)
+        when (serverCfg) {
+            is ServerConfig.Tcp -> {
+                logger.info("Server listening on 
http://localhost:${serverCfg.port}";)
+            }
+            is ServerConfig.Unix ->
+                throw Exception("Can only serve libeufin-bank via TCP")
+        }
+        engine.start(wait = true)
     }
 }
 
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
index b2eed27c..67de9f06 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/WireGatewayApi.kt
@@ -52,10 +52,7 @@ fun Routing.wireGatewayApi(db: Database, ctx: BankConfig) {
                 now = Instant.now()
             )
             when (res) {
-                is TransferResult.UnknownExchange -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                is TransferResult.UnknownExchange -> throw 
unknownAccount(username)
                 is TransferResult.NotAnExchange -> throw conflict(
                     "$username is not an exchange account.",
                     TalerErrorCode.BANK_ACCOUNT_IS_NOT_EXCHANGE
@@ -125,10 +122,7 @@ fun Routing.wireGatewayApi(db: Database, ctx: BankConfig) {
                 now = timestamp
             )
             when (res) {
-                is AddIncomingResult.UnknownExchange -> throw notFound(
-                    "Account '$username' not found",
-                    TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-                )
+                is AddIncomingResult.UnknownExchange -> throw 
unknownAccount(username)
                 is AddIncomingResult.NotAnExchange -> throw conflict(
                     "$username is not an exchange account.",
                     TalerErrorCode.BANK_ACCOUNT_IS_NOT_EXCHANGE
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
index 48b0fd6a..9c783af2 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/Database.kt
@@ -70,6 +70,14 @@ class Database(dbConfig: String, internal val bankCurrency: 
String, internal val
         config.connectionInitSql = "SET search_path TO libeufin_bank;SET 
SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;"
         config.validate()
         dbPool = HikariDataSource(config);
+        dbPool.getConnection().use { con -> 
+            val meta = con.getMetaData();
+            val majorVersion = meta.getDatabaseMajorVersion()
+            val minorVersion = meta.getDatabaseMinorVersion()
+            if (majorVersion < MIN_VERSION) {
+                throw Exception("postgres version must be at least 
$MIN_VERSION.0 got $majorVersion.$minorVersion")
+            }
+        }
         notifWatcher = NotificationWatcher(pgSource)
     }
 
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
index 2fdb957c..c8e96e0e 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/helpers.kt
@@ -49,10 +49,7 @@ fun ApplicationCall.expectUriComponent(componentName: 
String) =
 
 /** Retrieve the bank account info for the selected username*/
 suspend fun ApplicationCall.bankInfo(db: Database): BankInfo
-    = db.account.bankInfo(username) ?: throw notFound(
-        "Bank account for customer $username not found",
-        TalerErrorCode.BANK_UNKNOWN_ACCOUNT
-    )
+    = db.account.bankInfo(username) ?: throw unknownAccount(username)
 
 // Generates a new Payto-URI with IBAN scheme.
 fun genIbanPaytoUri(): String = "payto://iban/${getIban()}"
diff --git a/bank/src/test/kotlin/helpers.kt b/bank/src/test/kotlin/helpers.kt
index 3cef3f2c..c298fcb2 100644
--- a/bank/src/test/kotlin/helpers.kt
+++ b/bank/src/test/kotlin/helpers.kt
@@ -52,11 +52,13 @@ fun setup(
 ) {
     val config = talerConfig("conf/$conf")
     val dbCfg = config.loadDbConfig()
-    resetDatabaseTables(dbCfg, "libeufin-bank")
-    initializeDatabaseTables(dbCfg, "libeufin-bank")
     val ctx = config.loadBankConfig()
     Database(dbCfg.dbConnStr, ctx.regionalCurrency, ctx.fiatCurrency).use {
         runBlocking {
+            it.conn { conn ->
+                resetDatabaseTables(conn, dbCfg, "libeufin-bank")
+                initializeDatabaseTables(conn, dbCfg, "libeufin-bank")
+            }
             lambda(it, ctx)
         }
     }
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/DbInit.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/DbInit.kt
index 7a823624..a3cb3199 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/DbInit.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/DbInit.kt
@@ -3,8 +3,7 @@ package tech.libeufin.nexus
 import com.github.ajalt.clikt.core.CliktCommand
 import com.github.ajalt.clikt.parameters.options.flag
 import com.github.ajalt.clikt.parameters.options.option
-import tech.libeufin.util.initializeDatabaseTables
-import tech.libeufin.util.resetDatabaseTables
+import tech.libeufin.util.*
 import kotlin.system.exitProcess
 
 /**
@@ -25,10 +24,12 @@ class DbInit : CliktCommand("Initialize the libeufin-nexus 
database", name = "db
     override fun run() {
         val cfg = loadConfigOrFail(configFile).extractDbConfigOrFail()
         doOrFail {
-            if (requestReset) {
-                resetDatabaseTables(cfg, sqlFilePrefix = "libeufin-nexus")
+            pgDataSource(cfg.dbConnStr).pgConnection().use { conn ->
+                if (requestReset) {
+                    resetDatabaseTables(conn, cfg, sqlFilePrefix = 
"libeufin-nexus")
+                }
+                initializeDatabaseTables(conn, cfg, sqlFilePrefix = 
"libeufin-nexus")
             }
-            initializeDatabaseTables(cfg, sqlFilePrefix = "libeufin-nexus")
         }
     }
 }
\ No newline at end of file
diff --git a/nexus/src/test/kotlin/Common.kt b/nexus/src/test/kotlin/Common.kt
index ea9e67fd..82d31feb 100644
--- a/nexus/src/test/kotlin/Common.kt
+++ b/nexus/src/test/kotlin/Common.kt
@@ -4,9 +4,7 @@ import io.ktor.client.request.*
 import kotlinx.serialization.json.Json
 import kotlinx.serialization.modules.SerializersModule
 import tech.libeufin.nexus.*
-import tech.libeufin.util.DatabaseConfig
-import tech.libeufin.util.initializeDatabaseTables
-import tech.libeufin.util.resetDatabaseTables
+import tech.libeufin.util.*
 import java.security.interfaces.RSAPrivateCrtKey
 import java.time.Instant
 
@@ -28,14 +26,17 @@ fun prepDb(cfg: TalerConfig): Database {
         dbConnStr = "postgresql:///libeufincheck",
         sqlDir = cfg.requirePath("paths", "datadir") + "sql"
     )
-    println("SQL dir for testing: ${dbCfg.sqlDir}")
-    try {
-        resetDatabaseTables(dbCfg, "libeufin-nexus")
-    } catch (e: Exception) {
-        logger.warn("Resetting an empty database throws, tolerating this...")
-        logger.warn(e.message)
+    pgDataSource(dbCfg.dbConnStr).pgConnection().use { conn ->
+        println("SQL dir for testing: ${dbCfg.sqlDir}")
+        try {
+            resetDatabaseTables(conn, dbCfg, "libeufin-nexus")
+        } catch (e: Exception) {
+            logger.warn("Resetting an empty database throws, tolerating 
this...")
+            logger.warn(e.message)
+        }
+        initializeDatabaseTables(conn, dbCfg, "libeufin-nexus")
     }
-    initializeDatabaseTables(dbCfg, "libeufin-nexus")
+   
     return Database(dbCfg.dbConnStr)
 }
 
diff --git a/util/src/main/kotlin/DB.kt b/util/src/main/kotlin/DB.kt
index ccdd09c3..cfb204bf 100644
--- a/util/src/main/kotlin/DB.kt
+++ b/util/src/main/kotlin/DB.kt
@@ -224,60 +224,57 @@ fun maybeApplyV(conn: PgConnection, cfg: DatabaseConfig) {
 }
 
 // sqlFilePrefix is, for example, "libeufin-bank" or "libeufin-nexus" (no 
trailing dash).
-fun initializeDatabaseTables(cfg: DatabaseConfig, sqlFilePrefix: String) {
-    logger.info("doing DB initialization, sqldir ${cfg.sqlDir}, dbConnStr 
${cfg.dbConnStr}")
-    pgDataSource(cfg.dbConnStr).pgConnection().use { conn ->
-        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"
+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 = ?")
 
-                checkStmt.setString(1, patchName)
-                val patchCount = checkStmt.oneOrNull { it.getInt(1) } ?: throw 
Error("unable to query patches");
-                if (patchCount >= 1) {
-                    logger.info("patch $patchName already applied")
-                    continue
-                }
+        for (n in 1..9999) {
+            val numStr = n.toString().padStart(4, '0')
+            val patchName = "$sqlFilePrefix-$numStr"
 
-                val path = File("${cfg.sqlDir}/$sqlFilePrefix-$numStr.sql")
-                if (!path.exists()) {
-                    logger.info("path $path doesn't exist anymore, stopping")
-                    break
-                }
-                logger.info("applying patch $path")
-                val sqlPatchText = path.readText()
-                conn.execSQLUpdate(sqlPatchText)
+            checkStmt.setString(1, patchName)
+            val patchCount = checkStmt.oneOrNull { it.getInt(1) } ?: throw 
Error("unable to query patches");
+            if (patchCount >= 1) {
+                logger.info("patch $patchName already applied")
+                continue
             }
-            val sqlProcedures = 
File("${cfg.sqlDir}/$sqlFilePrefix-procedures.sql")
-            if (!sqlProcedures.exists()) {
-                logger.info("No procedures.sql for the SQL collection: 
$sqlFilePrefix")
-                return@transaction
+
+            val path = File("${cfg.sqlDir}/$sqlFilePrefix-$numStr.sql")
+            if (!path.exists()) {
+                logger.info("path $path doesn't exist anymore, stopping")
+                break
             }
-            conn.execSQLUpdate(sqlProcedures.readText())
+            logger.info("applying patch $path")
+            val sqlPatchText = path.readText()
+            conn.execSQLUpdate(sqlPatchText)
+        }
+        val sqlProcedures = File("${cfg.sqlDir}/$sqlFilePrefix-procedures.sql")
+        if (!sqlProcedures.exists()) {
+            logger.info("no procedures.sql for the SQL collection: 
$sqlFilePrefix")
+            return@transaction
         }
+        logger.info("run procedure.sql")
+        conn.execSQLUpdate(sqlProcedures.readText())
     }
 }
 
 // sqlFilePrefix is, for example, "libeufin-bank" or "libeufin-nexus" (no 
trailing dash).
-fun resetDatabaseTables(cfg: DatabaseConfig, sqlFilePrefix: String) {
-    logger.info("reset DB, sqldir ${cfg.sqlDir}, dbConnStr ${cfg.dbConnStr}")
-    pgDataSource(cfg.dbConnStr).pgConnection().use { conn ->
-        val isInitialized = conn.prepareStatement("SELECT EXISTS(SELECT 1 FROM 
information_schema.schemata WHERE schema_name='_v')").oneOrNull {
-            it.getBoolean(1)
-        }!!
-        if (!isInitialized) {
-            logger.info("versioning schema not present, not running drop sql")
-            return
-        }
+fun resetDatabaseTables(conn: PgConnection, cfg: DatabaseConfig, 
sqlFilePrefix: String) {
+    logger.info("reset DB, sqldir ${cfg.sqlDir}")
+    val isInitialized = conn.prepareStatement("SELECT EXISTS(SELECT 1 FROM 
information_schema.schemata WHERE schema_name='_v')").oneOrNull {
+        it.getBoolean(1)
+    }!!
+    if (!isInitialized) {
+        logger.info("versioning schema not present, not running drop sql")
+        return
+    }
 
-        val sqlDrop = File("${cfg.sqlDir}/$sqlFilePrefix-drop.sql").readText()
-        try {
-            conn.execSQLUpdate(sqlDrop)
-        } catch (e: Exception) {
-            // TODO Fix fail because precense of _v does not mean patch is 
applied
-        }
+    val sqlDrop = File("${cfg.sqlDir}/$sqlFilePrefix-drop.sql").readText()
+    try {
+        conn.execSQLUpdate(sqlDrop)
+    } catch (e: Exception) {
+        // TODO Fix fail because precense of _v does not mean patch is applied
     }
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]