From 2a5b7371d0b42a3d5b0cf510952e635a7be951ff Mon Sep 17 00:00:00 2001 From: cxyzhang0 Date: Tue, 24 Jul 2018 02:09:37 -0700 Subject: [PATCH] =?UTF-8?q?h2=20cash=20selection=20query=20to=20support=20?= =?UTF-8?q?multiple=20onlyFromIssuerParties=20and=E2=80=A6=20(#3659)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * h2 cash selection query to support multiple onlyFromIssuerParties and withIssuerRefs * Rid of the compilation warnings --- .../cash/selection/CashSelectionH2Impl.kt | 22 ++++++++++++------- .../cash/selection/CashSelectionH2ImplTest.kt | 9 ++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt index 7922ff79f2..bff90c053f 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt @@ -43,10 +43,14 @@ class CashSelectionH2Impl : AbstractCashSelection() { """ + (if (notary != null) " AND vs.notary_name = ?" else "") + - (if (onlyFromIssuerParties.isNotEmpty()) - " AND ccs.issuer_key_hash IN (?)" else "") + - (if (withIssuerRefs.isNotEmpty()) - " AND ccs.issuer_ref IN (?)" else "") + (if (onlyFromIssuerParties.isNotEmpty()) { + val repeats = generateSequence { "?" }.take(onlyFromIssuerParties.size).joinToString(",") + " AND ccs.issuer_key_hash IN ($repeats)" + } else "") + + (if (withIssuerRefs.isNotEmpty()) { + val repeats = generateSequence { "?" }.take(withIssuerRefs.size).joinToString(",") + " AND ccs.issuer_ref IN ($repeats)" + } else "") // Use prepared statement for protection against SQL Injection (http://www.h2database.com/html/advanced.html#sql_injection) connection.prepareStatement(selectJoin).use { psSelectJoin -> @@ -56,10 +60,12 @@ class CashSelectionH2Impl : AbstractCashSelection() { psSelectJoin.setString(++pIndex, lockId.toString()) if (notary != null) psSelectJoin.setString(++pIndex, notary.name.toString()) - if (onlyFromIssuerParties.isNotEmpty()) - psSelectJoin.setObject(++pIndex, onlyFromIssuerParties.map { it.owningKey.toStringShort() as Any }.toTypedArray()) - if (withIssuerRefs.isNotEmpty()) - psSelectJoin.setObject(++pIndex, withIssuerRefs.map { it.bytes as Any }.toTypedArray()) + onlyFromIssuerParties.forEach { + psSelectJoin.setString(++pIndex, it.owningKey.toStringShort()) + } + withIssuerRefs.forEach { + psSelectJoin.setBytes(++pIndex, it.bytes) + } log.debug { psSelectJoin.toString() } psSelectJoin.executeQuery().use { rs -> diff --git a/finance/src/test/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2ImplTest.kt b/finance/src/test/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2ImplTest.kt index c259e3a10d..0a1864d012 100644 --- a/finance/src/test/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2ImplTest.kt +++ b/finance/src/test/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2ImplTest.kt @@ -69,4 +69,13 @@ class CashSelectionH2ImplTest { val paymentResult = node.startFlow(CashPaymentFlow(999.POUNDS, node.info.legalIdentities[0], false)).getOrThrow() assertNotNull(paymentResult.recipient) } + + @Test + fun `multiple issuers in issuerConstraint condition`() { + val node = mockNet.createNode() + node.startFlow(CashIssueFlow(1.POUNDS, OpaqueBytes.of(1), mockNet.defaultNotaryIdentity)).getOrThrow() + val request = CashPaymentFlow.PaymentRequest(1.POUNDS, node.info.legalIdentities[0], true, setOf(node.info.legalIdentities[0], mockNet.defaultNotaryIdentity)) + val paymentResult = node.startFlow(CashPaymentFlow(request)).getOrThrow() + assertNotNull(paymentResult.recipient) + } } \ No newline at end of file