Search code examples
javascripthyperledger-composer

How to use query in Hyperledger composer logic.js if the query have multiple inputs?


for querying in logic.js I can use

await query('selectCommoditiesWithHighQuantity')

But how can I do that if I have multiple input? if the query have function like this

query selectCommoditiesByTimeAndOwnerAndDataType {
  description: "Select all commodities based on their sender country"
  statement:
      SELECT org.stock.mynetwork.Commodity
          WHERE(time  > _$from AND time < _$to AND owner == _$owner AND dataType == _$dataType)
}

how can I call that query from js side?

edit: js code

/**
 * Track the trade of a commodity from one trader to another
 * @param {org.stock.mynetwork.Receive} receive - the receive to be processed
 * @transaction
 */
async function receiveCommodity(receive) {

    let q1 = await buildQuery('SELECT org.stock.mynetwork.Commodity ' +
                                                'WHERE (productName == _$productName AND owner == _$owner)');


let result2 = await query(q1,{productName:receive.productName,owner: receive.newOwner});
}

there is a problem with let result2 = await query(q1,{productName:receive.productName,owner: receive.newOwner}); part. If I just use productName: receive.productName it works perfectly, but when I add owner: receive.newOwner it need serialize.json


Solution

  • So you can write a query inside the .qry file and call it, but I do not recommend doing that. You can make the same queries directly from the SDK and in the logic.js file. Reasoning behind this is, say a few days later, you want to add a new API that queries by a certain value, if you rely on the .qry file (which will work), then you will need to deploy a new version of smart contact, whereas if you use the SDK, you can do a change in the API and deploy a new application server asap.

    async function someTransaction(receive) {
      let assetRegistry = await getAssetRegistry('YOUR_NAME_SPACE');
      let ownerRegistry = await getParticipantRegistry('YOUR_NAME_SPACE');
    
      let statement = 'SELECT NAME_SPACE_OF_ASSET WHERE (owner == _$owner && dataType == _$dataType)';
      let qry = buildQuery(statement);
    
      // This query can be done in different ways
      // assuming newOwner is a string (id of participant)
      let allAssets = await query(qry, { owner: receive.newOwner, dataType: receive.dataType });
    
      // assuming newOwner is a participant
      let allAssets = await query(qry, { owner: receive.newOwner.getIdentifier(), dataType: receive.dataType });
    
      if (allAssets.length === 0) {
        // No assets exists, add one
        // use assetRegistry.add()
      } else {
        for (var i = 0; i < allAssets.length; i++) {
          // Iterate over assets belonging to an owner of a product type
          // Do whatever here
          // use assetRegistry.update()
        };
      };
    
    };