gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated: Implementing GET /transactions.


From: gnunet
Subject: [libeufin] branch master updated: Implementing GET /transactions.
Date: Mon, 18 Sep 2023 15:25:00 +0200

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

ms pushed a commit to branch master
in repository libeufin.

The following commit(s) were added to refs/heads/master by this push:
     new f632635b Implementing GET /transactions.
f632635b is described below

commit f632635b3292df19b5c204861eab7f74be07731b
Author: MS <ms@taler.net>
AuthorDate: Mon Sep 18 15:24:14 2023 +0200

    Implementing GET /transactions.
---
 .../src/main/kotlin/tech/libeufin/bank/Database.kt | 34 ++++++++-------
 .../tech/libeufin/bank/transactionsHandlers.kt     | 48 ++++++++++++++++++++++
 bank/src/main/kotlin/tech/libeufin/bank/types.kt   |  7 ++++
 bank/src/test/kotlin/DatabaseTest.kt               |  5 +--
 4 files changed, 77 insertions(+), 17 deletions(-)

diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
index be196676..34689a47 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
@@ -25,6 +25,7 @@ import java.sql.DriverManager
 import java.sql.PreparedStatement
 import java.sql.SQLException
 import java.util.*
+import kotlin.math.abs
 
 private const val DB_CTR_LIMIT = 1000000
 
@@ -485,14 +486,19 @@ class Database(private val dbConfig: String) {
             )
         }
     }
-
-    fun bankTransactionGetForHistoryPage(
-        upperBound: Long,
+    private data class HistoryParams(
+        val cmpOp: String, // < or >
+        val orderBy: String // ASC or DESC
+    )
+    fun bankTransactionGetHistory(
+        start: Long,
+        delta: Long,
         bankAccountId: Long,
-        fromMs: Long,
-        toMs: Long
     ): List<BankAccountTransaction> {
         reconnect()
+        val ops = if (delta < 0)
+            HistoryParams("<", "DESC") else
+                HistoryParams(">", "ASC")
         val stmt = prepare("""
             SELECT 
               creditor_payto_uri
@@ -508,15 +514,15 @@ class Database(private val dbConfig: String) {
               ,end_to_end_id
               ,direction
               ,bank_account_id
+              ,bank_transaction_id
             FROM bank_account_transactions
-               WHERE bank_transaction_id < ?
-              AND bank_account_id=?
-              AND transaction_date BETWEEN ? AND ?
+               WHERE bank_transaction_id ${ops.cmpOp} ? AND bank_account_id=?
+            ORDER BY bank_transaction_id ${ops.orderBy}
+            LIMIT ?
         """)
-        stmt.setLong(1, upperBound)
+        stmt.setLong(1, start)
         stmt.setLong(2, bankAccountId)
-        stmt.setLong(3, fromMs)
-        stmt.setLong(4, toMs)
+        stmt.setLong(3, abs(delta))
         val rs = stmt.executeQuery()
         rs.use {
             val ret = mutableListOf<BankAccountTransaction>()
@@ -544,9 +550,9 @@ class Database(private val dbConfig: String) {
                         bankAccountId = it.getLong("bank_account_id"),
                         paymentInformationId = 
it.getString("payment_information_id"),
                         subject = it.getString("subject"),
-                        transactionDate = it.getLong("transaction_date")
-                )
-                )
+                        transactionDate = it.getLong("transaction_date"),
+                        dbRowId = it.getLong("bank_transaction_id")
+                ))
             } while (it.next())
             return ret
         }
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt
index 0fe3ad69..2e315bdd 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/transactionsHandlers.kt
@@ -2,14 +2,62 @@ package tech.libeufin.bank
 
 import io.ktor.http.*
 import io.ktor.server.application.*
+import io.ktor.server.plugins.*
 import io.ktor.server.request.*
 import io.ktor.server.response.*
 import io.ktor.server.routing.*
 import net.taler.common.errorcodes.TalerErrorCode
 import tech.libeufin.util.getNowUs
 import tech.libeufin.util.parsePayto
+import kotlin.math.abs
 
 fun Routing.transactionsHandlers() {
+    get("/accounts/{USERNAME}/transactions") {
+        val c = call.myAuth(TokenScope.readonly) ?: throw unauthorized()
+        val resourceName = call.expectUriComponent("USERNAME")
+        if (c.login != resourceName && c.login != "admin") throw forbidden()
+        // Collecting params.
+        val deltaParam: String = call.request.queryParameters["delta"] ?: 
throw MissingRequestParameterException("Parameter 'delta' not found")
+        val delta: Long = try {
+            deltaParam.toLong()
+        } catch (e: Exception) {
+            logger.error(e.message)
+            throw badRequest("Param 'delta' not a number")
+        }
+        // Note: minimum 'start' is zero, as database IDs start from 1.
+        val start: Long = when (val param = 
call.request.queryParameters["start"]) {
+            null -> if (delta >= 0) 0L else Long.MAX_VALUE
+            else -> try {
+                param.toLong()
+            } catch (e: Exception) {
+                logger.error(e.message)
+                throw badRequest("Param 'start' not a number")
+            }
+        }
+        logger.info("Param long_poll_ms not supported")
+        // Making the query.
+        val bankAccount = db.bankAccountGetFromOwnerId(c.expectRowId())
+            ?: throw internalServerError("Customer '${c.login}' lacks bank 
account.")
+        val bankAccountId = bankAccount.bankAccountId
+            ?: throw internalServerError("Bank account lacks row ID.")
+        val history: List<BankAccountTransaction> = 
db.bankTransactionGetHistory(bankAccountId, start, delta)
+        val res = BankAccountTransactionsResponse(transactions = 
mutableListOf())
+        history.forEach {
+            res.transactions.add(BankAccountTransactionInfo(
+                debtor_payto_uri = it.debtorPaytoUri,
+                creditor_payto_uri = it.creditorPaytoUri,
+                subject = it.subject,
+                amount = it.amount.toString(),
+                direction = it.direction,
+                date = it.transactionDate,
+                row_id = it.dbRowId ?: throw internalServerError(
+                    "Transaction timestamped with '${it.transactionDate}' did 
not have row ID"
+                )
+            ))
+        }
+        call.respond(res)
+        return@get
+    }
     // Creates a bank transaction.
     post("/accounts/{USERNAME}/transactions") {
         val c = call.myAuth(TokenScope.readwrite) ?: throw unauthorized()
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/types.kt 
b/bank/src/main/kotlin/tech/libeufin/bank/types.kt
index d0d7d2c6..fd65d244 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/types.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/types.kt
@@ -289,6 +289,8 @@ data class BankAccountTransaction(
      * bank account of the payer.
      */
     val bankAccountId: Long,
+    // Null if this type is used to _create_ one transaction.
+    val dbRowId: Long? = null,
     // Following are ISO20022 specific.
     val accountServicerReference: String,
     val paymentInformationId: String,
@@ -372,4 +374,9 @@ data class BankAccountTransactionInfo(
     val subject: String,
     val row_id: Long, // is T_ID
     val date: Long
+)
+
+@Serializable
+data class BankAccountTransactionsResponse(
+    val transactions: MutableList<BankAccountTransactionInfo>
 )
\ No newline at end of file
diff --git a/bank/src/test/kotlin/DatabaseTest.kt 
b/bank/src/test/kotlin/DatabaseTest.kt
index 290d0d19..fc2a4f54 100644
--- a/bank/src/test/kotlin/DatabaseTest.kt
+++ b/bank/src/test/kotlin/DatabaseTest.kt
@@ -223,11 +223,10 @@ class DatabaseTest {
     @Test
     fun historyTest() {
         val db = initDb()
-        val res = db.bankTransactionGetForHistoryPage(
+        val res = db.bankTransactionGetHistory(
             10L,
             1L,
-            fromMs = 0,
-            toMs = Long.MAX_VALUE
+            1L
         )
         assert(res.isEmpty())
     }

-- 
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]