Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

I've been using the php-gds library as a way of connecting my app to the GAE Cloud Datastore for quite some time and until recently I didn't require pagination because I simply didn't have enough data, well that has changed and I needed to implement this feature. I knew that to get pagination working I had to have an efficient way of getting a count of all of the entities of the same kind - this wasn't possible with standard php-gds functions and certainly wasn't supported via GQL. But there must have been a way.

Sure, I could fetch all entities and count how many there were, but this was the most expensive and least efficient way of going about it, so it wasn't even an option.

I had some pretty wild ideas about how this could be achieved efficiently - including keeping track of how many entities of the same kind were created and looking that up as needed. Turned out that was exactly what Google was doing already! ...with the NDB Administration queries.

It was possible to issue a standard GQL query like 'select * from __Stat_Kind__' and get all sorts of statistics on entity kinds, including the total count!
pagination1.png


So I figured that since this was looking up what appeared to as a standard entity in the Datastore, I could make this work with php-gds. So I put together some simple test code. Since the __Stat_Kind__ entity kind was using other entity kinds as key names, I could look up whatever entity kind I wanted stats for easily...
 PHP
$obj_store = new GDS\Store('__Stat_Kind__');
$obj = $obj_store->fetchByName('AG_GameEntity');
error_log(var_export($obj, true));


It gave me results!
 Output
GDS\Entity::__set_state(array(
'str_kind' => '__Stat_Kind__',
'str_key_id' => NULL,
'str_key_name' => 'AG_GameEntity',
'mix_ancestry' => NULL,
'arr_data' =>
array (
'builtin_index_bytes' => '232913',
'builtin_index_count' => '4910',
'bytes' => '308001',
'composite_index_bytes' => '17478',
'composite_index_count' => '100',
'count' => '100',
'entity_bytes' => '57610',
'kind_name' => 'AG_GameEntity',
'timestamp' =>
DateTime::__set_state(array(
'date' => '2018-04-14 00:25:25.000000',
'timezone_type' => 1,
'timezone' => '+00:00',
)),
),
'obj_schema' =>
GDS\Schema::__set_state(array(
'str_kind' => '__Stat_Kind__',
'arr_defined_properties' =>
array (
),
'str_entity_class' => '\\GDS\\Entity',
)),
))




I was on the right track and I could get the total count of entities of the same kind with this query - all I had to do was get the value of the 'count' property from the returned entity. It was so simple!

From here it was a matter of writing code that used the fetchPage() function on the Store class and I was done. The actual pagination code after having the total count of entities was more or less trivial, so I won't cover that part here.

There was a small catch to testing this in the local dev server. Unlike the production Datastore, the local Datastore does not automatically generate entity statistics. These needed to be generated manually via the dev server console.
pagination2.png


-i

Hope you found this post useful...

...so please read on! I love writing articles that provide beneficial information, tips and examples to my readers. All information on my blog is provided free of charge and I encourage you to share it as you wish. There is a small favour I ask in return however - engage in comments below, provide feedback, and if you see mistakes let me know.

If you want to show additional support and help me pay for web hosting and domain name registration, donations, no matter how small, are always welcome!

Use of any information contained in this blog post/article is subject to this disclaimer.
comments powered by Disqus
Other posts you may like...