0

Let's suppose that we have following structures in Solidity contract :

struct EntityA {
string lessThen32ByteString1;
string moreThen32ByteString1;
string lessThen32ByteString2;
string moreThen32ByteString3;
bool flag;
uint var1;
uint var2;
uint var3;
uint var4;
ProposalStatus proposalStatus;}

// 100K entities EntityA[] public items;

We have now following implementation (with helper functions for string to byte32 conversion, splitting string to a few byte32 parts and so on) :

function getChunkOfPart1EntityADetails(uint filterAsUint, uint offset, uint limit) public constant
returns (bytes32[100] lessThen32ByteString1Arr, bytes32[100] moreThen32ByteString1PrefixArr, bytes32[100] moreThen32ByteString1SuffixArr) {
}

function getChunkOfPart2EntityADetails(uint filterAsUint, uint offset, uint limit) public constant
returns (bytes32[100] lessThen32ByteString2Arr, bytes32[100] moreThen32ByteString2PrefixArr, bytes32[100] moreThen32ByteString2SuffixArr) {
}

function getChunkOfPart3EntityADetails(uint filterAsUint, uint offset, uint limit) public constant
returns (bool[100] flagArr, uint[100] var1Arr, uint[100] var2Arr, uint[100] var3Arr, uint[100] var4Arr, ProposalStatus[100] proposalStatusArr,) {
}

Current implementation does not look good from design perspective, furthermore each additional filter support requires contract changes due to absence any query language support.

Use case example : retrieve 10 entities based on specified proposalStatus and offset 50 (6th page, page size is 10 entities (maybe 20, 50, 100))

Igor Golovan
  • 91
  • 2
  • 11

1 Answers1

1

I know I'm late but here you go. This will return an array of uints. You can then use this array on the client to resolve the id's in the getter for the array that stores your data.

struct Zombie {
  //data
};

Zombie[] public zombies;

function paginateAllZombies(uint _resultsPerPage, uint _page) external view returns (uint[]) {
  Zombie[] memory result = new Zombie[](_resultsPerPage);
  for(uint i = _resultsPerPage * _page - _resultsPerPage; i < _resultsPerPage * _page; i++ ){
      result[i] = i;
    } //CONVERT TO SAFEMATH
    return result;
}

So once you get this returned you can .map() the result in your client app and call zombies(uint _index).

If you need more details on this approach please check out cryptozombies.io

Not sure if this is the best approach though.

Hopefully in the future you can just do:

function paginateAllZombies(uint _resultsPerPage, uint _page) external view returns (Zombie[]) {
  uint[] memory result = new uint[](_resultsPerPage);
  for(uint i = _resultsPerPage * _page - _resultsPerPage; i < _resultsPerPage * _page; i++ ){
      result[i] = zombies[i];
    } //CONVERT TO SAFEMATH
    return result;
}
Nico
  • 131
  • 6
  • Sorry I'm too clueless to answer that question :D Self-thaught coder, not a master in computer science sadly. – Nico Mar 21 '18 at 18:12