|
22 | 22 | // [START datastore_use] |
23 | 23 | use Google\Cloud\Datastore\DatastoreClient; |
24 | 24 | // [END datastore_use] |
| 25 | +use Google\Cloud\Datastore\Entity; |
25 | 26 | use Google\Cloud\Datastore\Key; |
26 | 27 | use Google\Cloud\Datastore\Query\Query; |
27 | 28 |
|
@@ -725,3 +726,148 @@ function inequality_sort_invalid_not_first(DatastoreClient $datastore) |
725 | 726 | // [END inequality_sort_invalid_not_first] |
726 | 727 | return $query; |
727 | 728 | } |
| 729 | + |
| 730 | +/** |
| 731 | + * Create a query with an equality filter on 'description'. |
| 732 | + * |
| 733 | + * @param DatastoreClient $datastore |
| 734 | + * @return Query |
| 735 | + */ |
| 736 | +function unindexed_property_query(DatastoreClient $datastore) |
| 737 | +{ |
| 738 | + // [START unindexed_property_query] |
| 739 | + $query = $datastore->query() |
| 740 | + ->kind('Task') |
| 741 | + ->filter('description', '=', 'A task description.'); |
| 742 | + // [END unindexed_property_query] |
| 743 | + return $query; |
| 744 | +} |
| 745 | + |
| 746 | +/** |
| 747 | + * Create an entity with two array properties. |
| 748 | + * |
| 749 | + * @param DatastoreClient $datastore |
| 750 | + * @return Google\Cloud\Datastore\Entity |
| 751 | + */ |
| 752 | +function exploding_properties(DatastoreClient $datastore) |
| 753 | +{ |
| 754 | + // [START exploding_properties] |
| 755 | + $task = $datastore->entity( |
| 756 | + $datastore->key('Task'), |
| 757 | + [ |
| 758 | + 'tags' => ['fun', 'programming', 'learn'], |
| 759 | + 'collaborators' => ['alice', 'bob', 'charlie'], |
| 760 | + 'created' => new \DateTime(), |
| 761 | + ] |
| 762 | + ); |
| 763 | + // [END exploding_properties] |
| 764 | + return $task; |
| 765 | +} |
| 766 | + |
| 767 | +// [START transactional_update] |
| 768 | +/** |
| 769 | + * Update two entities in a transaction. |
| 770 | + * |
| 771 | + * @param DatastoreClient $datastore |
| 772 | + * @param Key $fromKey |
| 773 | + * @param Key $toKey |
| 774 | + * @param $amount |
| 775 | + */ |
| 776 | +function transfer_funds( |
| 777 | + DatastoreClient $datastore, |
| 778 | + Key $fromKey, |
| 779 | + Key $toKey, |
| 780 | + $amount |
| 781 | +) { |
| 782 | + $transaction = $datastore->transaction(); |
| 783 | + $result = $transaction->lookupBatch([$fromKey, $toKey]); |
| 784 | + if (count($result['found']) != 2) { |
| 785 | + $transaction->rollback(); |
| 786 | + } |
| 787 | + // Currently, the result from lookupBatch doesn't guarantee the same order |
| 788 | + // as the given keys with the client library. |
| 789 | + // TODO: remove this hack once the issue below is fixed. |
| 790 | + // https://github.com/GoogleCloudPlatform/google-cloud-php/issues/175 |
| 791 | + if ($result['found'][0]->key()->path() == $fromKey->path()) { |
| 792 | + $fromAccount = $result['found'][0]; |
| 793 | + $toAccount = $result['found'][1]; |
| 794 | + } else { |
| 795 | + $fromAccount = $result['found'][1]; |
| 796 | + $toAccount = $result['found'][0]; |
| 797 | + } |
| 798 | + $fromAccount['balance'] -= $amount; |
| 799 | + $toAccount['balance'] += $amount; |
| 800 | + $transaction->updateBatch([$fromAccount, $toAccount]); |
| 801 | + $transaction->commit(); |
| 802 | +} |
| 803 | +// [END transactional_update] |
| 804 | + |
| 805 | +/** |
| 806 | + * Call a function and retry upon conflicts for several times. |
| 807 | + * |
| 808 | + * @param DatastoreClient $datastore |
| 809 | + * @param Key $fromKey |
| 810 | + * @param Key $toKey |
| 811 | + */ |
| 812 | +function transactional_retry( |
| 813 | + DatastoreClient $datastore, |
| 814 | + Key $fromKey, |
| 815 | + Key $toKey |
| 816 | +) { |
| 817 | + // [START transactional_retry] |
| 818 | + $retries = 5; |
| 819 | + for ($i = 0; $i < $retries; $i++) { |
| 820 | + try { |
| 821 | + transfer_funds($datastore, $fromKey, $toKey, 10); |
| 822 | + } catch (Google\Cloud\Exception\ConflictException $e) { |
| 823 | + // if $i >= $retries, the failure is final |
| 824 | + continue; |
| 825 | + } |
| 826 | + // Succeeded! |
| 827 | + break; |
| 828 | + } |
| 829 | + // [END transactional_retry] |
| 830 | +} |
| 831 | + |
| 832 | +/** |
| 833 | + * Insert an entity only if there is no entity with the same key. |
| 834 | + * |
| 835 | + * @param DatastoreClient $datastore |
| 836 | + * @param Entity $task |
| 837 | + */ |
| 838 | +function get_or_create(DatastoreClient $datastore, Entity $task) |
| 839 | +{ |
| 840 | + // [START transactional_get_or_create] |
| 841 | + $transaction = $datastore->transaction(); |
| 842 | + $existed = $transaction->lookup($task->key()); |
| 843 | + if ($existed === null) { |
| 844 | + $transaction->insert($task); |
| 845 | + $transaction->commit(); |
| 846 | + } |
| 847 | + // [END transactional_get_or_create] |
| 848 | +} |
| 849 | + |
| 850 | +/** |
| 851 | + * Run a query with an ancestor inside a transaction. |
| 852 | + * |
| 853 | + * @param DatastoreClient $datastore |
| 854 | + * @return array<Entity> |
| 855 | + */ |
| 856 | +function get_task_list_entities(DatastoreClient $datastore) |
| 857 | +{ |
| 858 | + // [START transactional_single_entity_group_read_only] |
| 859 | + $transaction = $datastore->transaction(); |
| 860 | + $taskListKey = $datastore->key('TaskList', 'default'); |
| 861 | + $query = $datastore->query() |
| 862 | + ->kind('Task') |
| 863 | + ->filter('__key__', Query::OP_HAS_ANCESTOR, $taskListKey); |
| 864 | + $result = $transaction->runQuery($query); |
| 865 | + $taskListEntities = []; |
| 866 | + /* @var Entity $task */ |
| 867 | + foreach ($result as $task) { |
| 868 | + $taskListEntities[] = $task; |
| 869 | + } |
| 870 | + $transaction->commit(); |
| 871 | + // [END transactional_single_entity_group_read_only] |
| 872 | + return $taskListEntities; |
| 873 | +} |
0 commit comments