commit 53392e3316ce21ea9ca8254caf9c5a0811331387
parent c4fa1ddacc51d9bb2a1aa6020576d4a57bf7d021
Author: Antoine A <>
Date: Fri, 21 Jun 2024 14:45:02 +0200
common: clean more code
Diffstat:
5 files changed, 47 insertions(+), 33 deletions(-)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
@@ -131,7 +131,7 @@ class AccountDAO(private val db: Database) {
setString(5, phone)
setString(6, cashoutPayto?.full(name))
setString(7, tanChannel?.name)
- oneOrNull { it.getLong("customer_id") }!!
+ one { it.getLong("customer_id") }
}
conn.withStatement("""
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/ConversionDAO.kt
@@ -75,7 +75,7 @@ class ConversionDAO(private val db: Database) {
val roundingMode = conn.prepareStatement("SELECT config_get_rounding_mode(?)")
fun getAmount(name: String, currency: String): TalerAmount {
amount.setString(1, name)
- return amount.oneOrNull { it.getAmount("amount", currency) }!!
+ return amount.one { it.getAmount("amount", currency) }
}
fun getRatio(name: String): DecimalNumber = getAmount(name, "").run { DecimalNumber(value, frac) }
fun getMode(name: String): RoundingMode {
diff --git a/bank/src/test/kotlin/AmountTest.kt b/bank/src/test/kotlin/AmountTest.kt
@@ -21,7 +21,7 @@ import org.junit.Test
import tech.libeufin.bank.db.TransactionDAO.BankTransactionResult
import tech.libeufin.bank.db.WithdrawalDAO.WithdrawalCreationResult
import tech.libeufin.common.*
-import tech.libeufin.common.db.oneOrNull
+import tech.libeufin.common.db.one
import java.time.Instant
import java.util.*
import kotlin.test.assertEquals
@@ -141,16 +141,16 @@ class AmountTest {
fun normalize() = dbSetup { db ->
db.conn { conn ->
val stmt = conn.prepareStatement("SELECT normalized.val, normalized.frac FROM amount_normalize((?, ?)::taler_amount) as normalized")
- fun TalerAmount.normalize(): TalerAmount? {
+ fun TalerAmount.normalize(): TalerAmount {
stmt.setLong(1, value)
stmt.setInt(2, frac)
- return stmt.oneOrNull {
+ return stmt.one {
TalerAmount(
it.getLong(1),
it.getInt(2),
"EUR"
)
- }!!
+ }
}
assertEquals(TalerAmount("EUR:6"), TalerAmount(4L, 2 * TalerAmount.FRACTION_BASE, "EUR").normalize())
@@ -158,6 +158,10 @@ class AmountTest {
assertEquals(TalerAmount("EUR:${TalerAmount.MAX_VALUE}.99999999"), TalerAmount("EUR:${TalerAmount.MAX_VALUE}.99999999").normalize())
assertException("ERROR: bigint out of range") { TalerAmount(Long.MAX_VALUE, TalerAmount.FRACTION_BASE, "EUR").normalize() }
assertException("ERROR: amount value overflowed") { TalerAmount(TalerAmount.MAX_VALUE, TalerAmount.FRACTION_BASE , "EUR").normalize() }
+
+ for (amount in listOf(TalerAmount.max("EUR"), TalerAmount.zero("EUR"))) {
+ assertEquals(amount, amount.normalize())
+ }
}
}
@@ -165,20 +169,21 @@ class AmountTest {
fun add() = dbSetup { db ->
db.conn { conn ->
val stmt = conn.prepareStatement("SELECT sum.val, sum.frac FROM amount_add((?, ?)::taler_amount, (?, ?)::taler_amount) as sum")
- operator fun TalerAmount.plus(increment: TalerAmount): TalerAmount? {
+ operator fun TalerAmount.plus(increment: TalerAmount): TalerAmount {
stmt.setLong(1, value)
stmt.setInt(2, frac)
stmt.setLong(3, increment.value)
stmt.setInt(4, increment.frac)
- return stmt.oneOrNull {
+ return stmt.one {
TalerAmount(
it.getLong(1),
it.getInt(2),
"EUR"
)
- }!!
+ }
}
-
+ assertEquals(TalerAmount.max("EUR"), TalerAmount.max("EUR") + TalerAmount.zero("EUR"))
+ assertEquals(TalerAmount.zero("EUR"), TalerAmount.zero("EUR") + TalerAmount.zero("EUR"))
assertEquals(TalerAmount("EUR:6.41") + TalerAmount("EUR:4.69"), TalerAmount("EUR:11.1"))
assertEquals(TalerAmount("EUR:${TalerAmount.MAX_VALUE}") + TalerAmount("EUR:0.99999999"), TalerAmount("EUR:${TalerAmount.MAX_VALUE}.99999999"))
assertException("ERROR: amount value overflowed") { TalerAmount(TalerAmount.MAX_VALUE - 5, 0, "EUR") + TalerAmount(6, 0, "EUR") }
@@ -191,7 +196,7 @@ class AmountTest {
@Test
fun conversionApply() = dbSetup { db ->
db.conn { conn ->
- fun apply(nb: TalerAmount, times: DecimalNumber, tiny: DecimalNumber = DecimalNumber("0.00000001"), roundingMode: String = "zero"): TalerAmount? {
+ fun apply(nb: TalerAmount, times: DecimalNumber, tiny: DecimalNumber = DecimalNumber("0.00000001"), roundingMode: String = "zero"): TalerAmount {
val stmt = conn.prepareStatement("SELECT amount.val, amount.frac FROM conversion_apply_ratio((?, ?)::taler_amount, (?, ?)::taler_amount, (?, ?)::taler_amount, ?::rounding_mode) as amount")
stmt.setLong(1, nb.value)
stmt.setInt(2, nb.frac)
@@ -200,13 +205,13 @@ class AmountTest {
stmt.setLong(5, tiny.value)
stmt.setInt(6, tiny.frac)
stmt.setString(7, roundingMode)
- return stmt.oneOrNull {
+ return stmt.one {
TalerAmount(
it.getLong(1),
it.getInt(2),
nb.currency
)
- }!!
+ }
}
assertEquals(TalerAmount("EUR:30.0629"), apply(TalerAmount("EUR:6.41"), DecimalNumber("4.69")))
@@ -255,7 +260,7 @@ class AmountTest {
@Test
fun conversionRevert() = dbSetup { db ->
db.conn { conn ->
- fun TalerAmount.apply(ratio: DecimalNumber, tiny: DecimalNumber = DecimalNumber("0.00000001"), roundingMode: String = "zero"): TalerAmount? {
+ fun TalerAmount.apply(ratio: DecimalNumber, tiny: DecimalNumber = DecimalNumber("0.00000001"), roundingMode: String = "zero"): TalerAmount {
val stmt = conn.prepareStatement("SELECT amount.val, amount.frac FROM conversion_apply_ratio((?, ?)::taler_amount, (?, ?)::taler_amount, (?, ?)::taler_amount, ?::rounding_mode) as amount")
stmt.setLong(1, this.value)
stmt.setInt(2, this.frac)
@@ -264,16 +269,16 @@ class AmountTest {
stmt.setLong(5, tiny.value)
stmt.setInt(6, tiny.frac)
stmt.setString(7, roundingMode)
- return stmt.oneOrNull {
+ return stmt.one {
TalerAmount(
it.getLong(1),
it.getInt(2),
currency
)
- }!!
+ }
}
- fun TalerAmount.revert(ratio: DecimalNumber, tiny: DecimalNumber = DecimalNumber("0.00000001"), roundingMode: String = "zero"): TalerAmount? {
+ fun TalerAmount.revert(ratio: DecimalNumber, tiny: DecimalNumber = DecimalNumber("0.00000001"), roundingMode: String = "zero"): TalerAmount {
val stmt = conn.prepareStatement("SELECT amount.val, amount.frac FROM conversion_revert_ratio((?, ?)::taler_amount, (?, ?)::taler_amount, (?, ?)::taler_amount, ?::rounding_mode) as amount")
stmt.setLong(1, this.value)
stmt.setInt(2, this.frac)
@@ -282,13 +287,13 @@ class AmountTest {
stmt.setLong(5, tiny.value)
stmt.setInt(6, tiny.frac)
stmt.setString(7, roundingMode)
- return stmt.oneOrNull {
+ return stmt.one {
TalerAmount(
it.getLong(1),
it.getInt(2),
currency
)
- }!!
+ }
}
assertEquals(TalerAmount("EUR:6.41"), TalerAmount("EUR:30.0629").revert(DecimalNumber("4.69")))
@@ -308,11 +313,11 @@ class AmountTest {
val ratio = DecimalNumber(ratio)
val base = TalerAmount("EUR:$amount")
// Apply ratio
- val rounded = base.apply(ratio, tiny, mode)!!
+ val rounded = base.apply(ratio, tiny, mode)
// Revert ratio
- val revert = rounded.revert(ratio, tiny, mode)!!
+ val revert = rounded.revert(ratio, tiny, mode)
// Check applying ratio again give the same result
- val check = revert.apply(ratio, tiny, mode)!!
+ val check = revert.apply(ratio, tiny, mode)
assertEquals(rounded, check)
}
}
diff --git a/bank/src/test/kotlin/DatabaseTest.kt b/bank/src/test/kotlin/DatabaseTest.kt
@@ -23,6 +23,7 @@ import kotlinx.coroutines.launch
import org.junit.Test
import tech.libeufin.bank.createAdminAccount
import tech.libeufin.bank.db.AccountDAO.AccountCreationResult
+import tech.libeufin.common.db.one
import tech.libeufin.common.db.oneOrNull
import tech.libeufin.common.*
import java.time.Duration
@@ -121,23 +122,23 @@ class DatabaseTest {
createStmt.setLong(2, ChronoUnit.MICROS.between(Instant.EPOCH, timestamp))
createStmt.setLong(3, TimeUnit.MICROSECONDS.convert(validityPeriod))
createStmt.setInt(4, retryCounter)
- return createStmt.oneOrNull { it.getLong(1) }!!
+ return createStmt.one { it.getLong(1) }
}
fun markSent(id: Long, timestamp: Instant) {
markSentStmt.setLong(1, id)
markSentStmt.setLong(2, ChronoUnit.MICROS.between(Instant.EPOCH, timestamp))
markSentStmt.setLong(3, TimeUnit.MICROSECONDS.convert(retransmissionPeriod))
- return markSentStmt.oneOrNull { }!!
+ return markSentStmt.one { }
}
fun cTry(id: Long, code: String, timestamp: Instant): Triple<Boolean, Boolean, Boolean> {
tryStmt.setLong(1, id)
tryStmt.setString(2, code)
tryStmt.setLong(3, ChronoUnit.MICROS.between(Instant.EPOCH, timestamp))
- return tryStmt.oneOrNull {
+ return tryStmt.one {
Triple(it.getBoolean(1), it.getBoolean(2), it.getBoolean(3))
- }!!
+ }
}
fun send(id: Long, code: String, timestamp: Instant): String? {
diff --git a/common/src/main/kotlin/TalerCommon.kt b/common/src/main/kotlin/TalerCommon.kt
@@ -120,12 +120,17 @@ class DecimalNumber {
constructor(encoded: String) {
val match = PATTERN.matchEntire(encoded) ?: throw badRequest("Invalid decimal number format")
val (value, frac) = match.destructured
- this.value = value.toLongOrNull() ?: throw badRequest("Invalid value")
- if (this.value > TalerAmount.MAX_VALUE) throw badRequest("Value specified in decimal number is too large")
+ this.value = value.toLongOrNull() ?:
+ throw badRequest("Invalid value")
+ if (this.value > TalerAmount.MAX_VALUE)
+ throw badRequest("Value specified in decimal number is too large")
this.frac = if (frac.isEmpty()) {
0
} else {
- var tmp = frac.toIntOrNull() ?: throw badRequest("Invalid fractional value")
+ var tmp = frac.toIntOrNull() ?:
+ throw badRequest("Invalid fractional value")
+ if (tmp > TalerAmount.FRACTION_BASE)
+ throw badRequest("Fractional value specified in decimal number is too large")
repeat(8 - frac.length) {
tmp *= 10
}
@@ -237,6 +242,7 @@ class TalerAmount {
private val PATTERN = Regex("([A-Z]{1,11}):([0-9]+)(?:\\.([0-9]{1,8}))?")
fun zero(currency: String) = TalerAmount(0, 0, currency)
+ fun max(currency: String) = TalerAmount(MAX_VALUE, FRACTION_BASE-1, currency)
}
}
@@ -479,8 +485,9 @@ class Base32Crockford32B {
}
fun encoded(): String {
- encoded = encoded ?: Base32Crockford.encode(raw)
- return encoded!!
+ val tmp = encoded ?: Base32Crockford.encode(raw)
+ encoded = tmp
+ return tmp
}
override fun toString(): String {
@@ -533,8 +540,9 @@ class Base32Crockford64B {
}
fun encoded(): String {
- encoded = encoded ?: Base32Crockford.encode(raw)
- return encoded!!
+ val tmp = encoded ?: Base32Crockford.encode(raw)
+ encoded = tmp
+ return tmp
}
override fun toString(): String {