[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] 02/02: implement history API
From: |
gnunet |
Subject: |
[libeufin] 02/02: implement history API |
Date: |
Tue, 11 Jan 2022 13:32:09 +0100 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
commit 225bc67cbecee0f031bf3dfb4d1288235d0720da
Author: ms <ms@taler.net>
AuthorDate: Sun Jan 9 16:15:47 2022 +0100
implement history API
---
.../src/main/kotlin/tech/libeufin/sandbox/DB.kt | 19 ++++++++++++
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 36 +++++++++++++++++-----
2 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index 6e86b844..caf82ad5 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -338,10 +338,21 @@ object BankAccountTransactionsTable : LongIdTable() {
class BankAccountTransactionEntity(id: EntityID<Long>) : LongEntity(id) {
companion object :
LongEntityClass<BankAccountTransactionEntity>(BankAccountTransactionsTable) {
override fun new(init: BankAccountTransactionEntity.() -> Unit):
BankAccountTransactionEntity {
+ /**
+ * Fresh transactions are those that wait to be included in a
+ * "history" report, likely a Camt.5x message. The "fresh
transactions"
+ * table keeps a list of such transactions.
+ */
val freshTx = super.new(init)
BankAccountFreshTransactionsTable.insert {
it[transactionRef] = freshTx.id
}
+ /**
+ * The bank account involved in this transaction points to
+ * it as the "last known" transaction, to make it easier to
+ * build histories that depend on such record.
+ */
+ freshTx.account.lastTransaction = freshTx
return freshTx
}
}
@@ -384,6 +395,13 @@ object BankAccountsTable : IntIdTable() {
val owner = text("owner")
val isPublic = bool("isPublic").default(false)
val demoBank = reference("demoBank", DemobankConfigsTable)
+
+ /**
+ * Point to the last transaction related to this account, regardless
+ * of it being credit or debit. This reference helps to construct
+ * history results that start from / depend on the last transaction.
+ */
+ val lastTransaction = reference("lastTransaction",
BankAccountTransactionsTable).nullable()
}
class BankAccountEntity(id: EntityID<Int>) : IntEntity(id) {
@@ -395,6 +413,7 @@ class BankAccountEntity(id: EntityID<Int>) : IntEntity(id) {
var owner by BankAccountsTable.owner
var isPublic by BankAccountsTable.isPublic
var demoBank by DemobankConfigEntity referencedOn
BankAccountsTable.demoBank
+ var lastTransaction by BankAccountTransactionEntity optionalReferencedOn
BankAccountsTable.lastTransaction
}
object BankAccountStatementsTable : IntIdTable() {
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index e3212e27..a74fd970 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -1279,8 +1279,7 @@ val sandboxApp: Application.() -> Unit = {
})
return@get
}
- // This endpoint is being called "GET /transaction" in the
docs.
- get("/accounts/{account_name}/history") {
+ get("/accounts/{account_name}/transactions") {
val demobank = ensureDemobank(call)
val bankAccount = getBankAccountFromLabel(
call.getUriComponent("account_name"),
@@ -1290,13 +1289,36 @@ val sandboxApp: Application.() -> Unit = {
if (!authOk && (call.request.basicAuth() !=
bankAccount.owner)) throw forbidden(
"Cannot access bank account ${bankAccount.label}"
)
+
+ val page: Int =
Integer.decode(call.request.queryParameters["page"] ?: "1")
+ val size: Int =
Integer.decode(call.request.queryParameters["size"] ?: "5")
+
val ret = mutableListOf<RawPayment>()
+ /**
+ * Case where page number wasn't given,
+ * therefore the results starts from the last transaction.
*/
transaction {
- BankAccountTransactionEntity.find {
- BankAccountTransactionsTable.account eq
bankAccount.id
- // FIXME: more criteria to come.
- }.forEach {
- ret.add(getHistoryElementFromTransactionRow(it))
+ /**
+ * Get a history page - from the calling bank account
- having
+ * 'firstElementId' as the latest transaction in it.
*/
+ fun getPage(firstElementId: Long):
Iterable<BankAccountTransactionEntity> {
+ return BankAccountTransactionEntity.find {
+ (BankAccountTransactionsTable.id lessEq
firstElementId) and
+ (BankAccountTransactionsTable.account
eq bankAccount.id)
+ }.take(size)
+ }
+ val lt: BankAccountTransactionEntity? =
bankAccount.lastTransaction
+ if (lt == null) return@transaction
+ var firstElement: BankAccountTransactionEntity = lt
+ /**
+ * This loop fetches (and discards) pages until the
+ * desired one is found. */
+ for (i in 0..(page)) {
+ val pageBuf = getPage(firstElement.id.value)
+ firstElement = pageBuf.last()
+ if (i == page) pageBuf.forEach {
+
ret.add(getHistoryElementFromTransactionRow(it))
+ }
}
}
call.respond(ret)
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.