Add queryFilter to triggers (#13769)

* Add queryFilter to triggers

changelog_begin

- [Daml Triggers] Add `queryFilter` matching Daml Script’s
  `queryFilter` which queries contracts of a given template and filters
  them down to those where the predicate holds.

changelog_end

fixes #13746

* Update triggers/daml/Daml/Trigger.daml
This commit is contained in:
Moritz Kiefer 2022-05-02 19:36:57 +02:00 committed by GitHub
parent 61cb257225
commit d3280ac87d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 0 deletions

View File

@ -5,6 +5,7 @@
module Daml.Trigger
( query
, queryFilter
, queryContractId
, queryContractKey
, ActionTriggerAny
@ -88,6 +89,11 @@ getContractById id (ACS tpls pending) = do
query : forall a m. (Template a, ActionTriggerAny m) => m [(ContractId a, a)]
query = implQuery
-- | Extract the contracts of a given template from the ACS and filter
-- to those that match the predicate.
queryFilter : forall a m. (Functor m, Template a, ActionTriggerAny m) => (a -> Bool) -> m [(ContractId a, a)]
queryFilter pred = filter (\(_, c) -> pred c) <$> implQuery
-- | Find the contract with the given `key` in the ACS, if present.
queryContractKey : forall a k m. (Template a, HasKey a k, Eq k, ActionTriggerAny m, Functor m)
=> k -> m (Optional (ContractId a, a))

View File

@ -42,6 +42,7 @@ DAML_LF_VERSIONS = [
cp -L $(location :daml/Heartbeat.daml) $$TMP_DIR/daml
cp -L $(location :daml/ReadAs.daml) $$TMP_DIR/daml
cp -L $(location :daml/ActAs.daml) $$TMP_DIR/daml
cp -L $(location :daml/QueryFilter.daml) $$TMP_DIR/daml
cp -L $(location //templates:copy-trigger/src/CopyTrigger.daml) $$TMP_DIR/daml
cp -L $(location //triggers/daml:daml-trigger{suffix}.dar) $$TMP_DIR/daml-trigger.dar
cp -L $(location //daml-script/daml:daml-script{suffix}.dar) $$TMP_DIR/daml-script.dar

View File

@ -0,0 +1,31 @@
-- Copyright (c) 2022 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0
module QueryFilter where
import Daml.Trigger
trigger : Trigger (Int, Int, Bool)
trigger = Trigger
{ initialize = pure (0, 0, False)
, updateState = const (pure ())
, rule = \p -> do
(_, _, started) <- get
if not started
then
emitCommands [createCmd (T p 1), createCmd (T p 2), createCmd (T p 2)] [] >> put (0, 0, True)
else do
xs <- queryFilter @T (\t -> t.i == 1)
ys <- queryFilter @T (\t -> t.i == 2)
put (length xs, length ys, started)
, registeredTemplates = AllInDar
, heartbeat = None
}
template T
with
p : Party
i : Int
where
signatory p

View File

@ -584,5 +584,30 @@ abstract class AbstractFuncTests
}
}
}
"queryFilter" should {
"return contracts matching predicates" in {
for {
client <- ledgerClient()
party <- allocateParty(client)
runner = getRunner(
client,
QualifiedName.assertFromString("QueryFilter:trigger"),
party,
)
(acs, offset) <- runner.queryACS()
// 1 for the completion & 1 for the transaction.
result <- runner.runWithACS(acs, offset, msgFlow = Flow[TriggerMsg].take(2))._2
} yield {
inside(toHighLevelResult(result).state) { case SRecord(_, _, values) =>
values.asScala shouldBe Seq[SValue](
SInt64(1),
SInt64(2),
SBool(true),
)
}
}
}
}
}
}