tomwalder / php-gds

Google Cloud Datastore Library for PHP
Apache License 2.0
164 stars 44 forks source link

Ancestry becomes out of order after fetching #61

Open danspano opened 9 years ago

danspano commented 9 years ago

Hi, firstly thank you for this extremely useful library, it has saved me so much time and helped me learn a lot about GDS very quickly.

I have found a strange issue when dealing with multi level, mutli kind ancestry, let me try to explain.

I have an ancestry like this: Site > Page > PageDesign

All queries with Site and Page entities behave as normal. When I create a new PageDesign entity and I use setAncestry I pass in a Page entity. This upserts perfectly and I can see in GDS the ancestry is correctly defined (Site > Page > PageDesign).

When I retrieve a PageDesign entity, by any means, all ancestry data is retrieved and stored within GDS\Entity as expected, however, the GDS library is not correctly parsing this ancestry, so subsequent queries (upsert, delete) are being made with the wrong ancestry ( Page > Site > PageDesign).

I have found a workaround for this issue, which is to getAncestry then setAncestry again, this corrects the internals of the GDS\Entity, allowing it to be properly parsed on next query.

I believe this is a problem with the Mapper? Or maybe when the ancestry is being read into the array it is in the wrong order.

I have dumped an example of a GDS\Entity which is correctly handled by queries and one which upserts the wrong ancestry, or does not delete because it is querying the wrong ancestry.

Here is a an example of an object which does NOT work (Ancestry out of order) this was fetched directly from GDS\Store: object(GDS\Entity)#189 (6) { ["str_kind":"GDS\Entity":private]=> string(10) "PageDesign" ["str_key_id":"GDS\Entity":private]=> string(16) "5668600916475904" ["str_key_name":"GDS\Entity":private]=> NULL ["mix_ancestry":"GDS\Entity":private]=> array(2) { [0]=> array(3) { ["kind"]=> string(4) "Site" ["id"]=> string(16) "5664902681198592" ["name"]=> NULL } [1]=> array(3) { ["kind"]=> string(4) "Page" ["id"]=> string(16) "5629499534213120" ["name"]=> NULL } } ["arr_data":"GDS\Entity":private]=> array(1) { ["notes"]=> string(18) "test notes" } ["obj_schema":"GDS\Entity":private]=> object(GDS\Schema)#172 (3) { ["str_kind":"GDS\Schema":private]=> string(10) "PageDesign" ["arr_defined_properties":"GDS\Schema":private]=> array(0) { } ["str_entity_class":"GDS\Schema":private]=> string(11) "\GDS\Entity" } }

You can see the shorthand ancestry in array form.

After calling getAncestry and then using the result to setAncestry, you get this object which DOES correclty upsert and delete from GDS: object(GDS\Entity)#175 (6) { ["str_kind":"GDS\Entity":private]=> string(10) "PageDesign" ["str_key_id":"GDS\Entity":private]=> string(16) "5668600916475904" ["str_key_name":"GDS\Entity":private]=> NULL ["mix_ancestry":"GDS\Entity":private]=> object(GDS\Entity)#179 (6) { ["str_kind":"GDS\Entity":private]=> string(4) "Page" ["str_key_id":"GDS\Entity":private]=> string(16) "5629499534213120" ["str_key_name":"GDS\Entity":private]=> NULL ["mix_ancestry":"GDS\Entity":private]=> array(1) { [0]=> array(3) { ["kind"]=> string(4) "Site" ["id"]=> string(16) "5664902681198592" ["name"]=> NULL } } ["arr_data":"GDS\Entity":private]=> array(1) { ["name"]=> string(7) "pageOne" } ["obj_schema":"GDS\Entity":private]=> object(GDS\Schema)#180 (3) { ["str_kind":"GDS\Schema":private]=> string(4) "Page" ["arr_defined_properties":"GDS\Schema":private]=> array(0) { } ["str_entity_class":"GDS\Schema":private]=> string(11) "\GDS\Entity" } } ["arr_data":"GDS\Entity":private]=> array(1) { ["notes"]=> string(18) "test notes" } ["obj_schema":"GDS\Entity":private]=> object(GDS\Schema)#176 (3) { ["str_kind":"GDS\Schema":private]=> string(10) "PageDesign" ["arr_defined_properties":"GDS\Schema":private]=> array(0) { } ["str_entity_class":"GDS\Schema":private]=> string(11) "\GDS\Entity" } }

I hope I have provided enough detail to explain the issue. Unfortunately the workaround of getAncestry/setAncestry means I have to loop data sets when trying to upsert/delete entity groups.

Hopefully this can be resolved. Thanks again for such a helpful library!

tomwalder commented 9 years ago

Hi there.

Just to let you know I've been super busy the last few days, but will take a look at your issue ASAP!

Tom

tomwalder commented 8 years ago

Thanks for the super detailed report - I'm pretty sure I know where to go for the fix.

tomwalder commented 8 years ago

Hi there,

I have done some work on this with the latest version (2) and using the Protocol Buffer gateway/mappers. I have not yet been able to replicate the problem.

Can you confirm which version of the library you are using and which gateway (ProtoBuf or the GoogleAPIClient for remote JSON API).

Cheers!

danspano commented 8 years ago

Hi Tom,

The only dependencies in my composer file are php-gds and google/apiclient. Currently installed versions: google/apiclient 1.1.3 tomwalder/php-gds v2.0.1

Dan

tomwalder commented 7 years ago

As per commit above, I was able to replicate this in the REST API Mapper.

I need to review the ProtoBuf and older GoogleAPIClient Mapper to see if the bug manifests there too.