in ngo-chaincode/src/ngo.js [53:133]
async function queryByString(stub, queryString) {
console.log('============= START : queryByString ===========');
console.log("##### queryByString queryString: " + queryString);
// CouchDB Query
// let iterator = await stub.getQueryResult(queryString);
// Equivalent LevelDB Query. We need to parse queryString to determine what is being queried
// In this chaincode, all queries will either query ALL records for a specific docType, or
// they will filter ALL the records looking for a specific NGO, Donor, Donation, etc. So far,
// in this chaincode there is a maximum of one filter parameter in addition to the docType.
let docType = "";
let startKey = "";
let endKey = "";
let jsonQueryString = JSON.parse(queryString);
if (jsonQueryString['selector'] && jsonQueryString['selector']['docType']) {
docType = jsonQueryString['selector']['docType'];
startKey = docType + "0";
endKey = docType + "z";
}
else {
throw new Error('##### queryByString - Cannot call queryByString without a docType element: ' + queryString);
}
let iterator = await stub.getStateByRange(startKey, endKey);
// Iterator handling is identical for both CouchDB and LevelDB result sets, with the
// exception of the filter handling in the commented section below
let allResults = [];
while (true) {
let res = await iterator.next();
if (res.value && res.value.value.toString()) {
let jsonRes = {};
console.log('##### queryByString iterator: ' + res.value.value.toString('utf8'));
jsonRes.Key = res.value.key;
try {
jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
}
catch (err) {
console.log('##### queryByString error: ' + err);
jsonRes.Record = res.value.value.toString('utf8');
}
// ******************* LevelDB filter handling ******************************************
// LevelDB: additional code required to filter out records we don't need
// Check that each filter condition in jsonQueryString can be found in the iterator json
// If we are using CouchDB, this isn't required as rich query supports selectors
let jsonRecord = jsonQueryString['selector'];
// If there is only a docType, no need to filter, just return all
console.log('##### queryByString jsonRecord - number of JSON keys: ' + Object.keys(jsonRecord).length);
if (Object.keys(jsonRecord).length == 1) {
allResults.push(jsonRes);
continue;
}
for (var key in jsonRecord) {
if (jsonRecord.hasOwnProperty(key)) {
console.log('##### queryByString jsonRecord key: ' + key + " value: " + jsonRecord[key]);
if (key == "docType") {
continue;
}
console.log('##### queryByString json iterator has key: ' + jsonRes.Record[key]);
if (!(jsonRes.Record[key] && jsonRes.Record[key] == jsonRecord[key])) {
// we do not want this record as it does not match the filter criteria
continue;
}
allResults.push(jsonRes);
}
}
// ******************* End LevelDB filter handling ******************************************
// For CouchDB, push all results
// allResults.push(jsonRes);
}
if (res.done) {
await iterator.close();
console.log('##### queryByString all results: ' + JSON.stringify(allResults));
console.log('============= END : queryByString ===========');
return Buffer.from(JSON.stringify(allResults));
}
}
}