Keys are unique identifiers for entities. Keys may be considered either "named" or "incomplete". A named Key is one in which each element of the Key path specify a Kind and a Name or ID. An incomplete Key omits the Name or ID from the final path element. Named Keys are required for any lookup, update, upsert or delete operations. They may also be used for inserting records, so long as you are certain that the identifier is available in Datastore. Incomplete Keys may be used for inserting records into Datastore. When an incomplete Key is used, Datastore will allocate an ID before inserting. Incomplete Keys are useful for guaranteeing the availability of an identifier without requiring an additional operation to check whether a given name or ID is available. Key state can be checked by calling Key::state(). The return will be one of Key::STATE_NAMED or Key::STATE_INCOMPLETE. Example: use Google\Cloud\ServiceBuilder; $cloud = new ServiceBuilder(); $datastore = $cloud->datastore(); $key = $datastore->key('Person', 'Bob'); Keys with complex paths can be constructed with additional method calls. $key = $datastore->key('Person', 'Bob'); $key->ancestor('Parents', 'Joe'); $key->ancestor('Grandparents', 'Barb'); Path elements can also be appended, so long as the current last path element contains a kind and identifier. $key = $datastore->key('Grandparents', 'Barb'); $key->pathElement('Parents', 'Joe'); $key->pathElement('Person'); $key->pathElement('Child', 'Dave'); // Error here.
See also: https://cloud.google.com/datastore/reference/rest/v1/Key Key
Inheritance: implements JsonSerializabl\JsonSerializable, use trait Google\Cloud\ArrayTrait, use trait DatastoreTrait
 /**
  * @expectedException PHPUnit_Framework_Error_Warning
  */
 public function testGcWithException()
 {
     $key1 = new Key('projectid');
     $key1->pathElement(self::KIND, 'sessionid1');
     $key2 = new Key('projectid');
     $key2->pathElement(self::KIND, 'sessionid2');
     $entity1 = new Entity($key1);
     $entity2 = new Entity($key2);
     $query = $this->prophesize(Query::class);
     $query->kind(self::KIND)->shouldBeCalledTimes(1)->willReturn($query->reveal());
     $that = $this;
     $query->filter(Argument::type('string'), Argument::type('string'), Argument::type('int'))->shouldBeCalledTimes(1)->will(function ($args) use($that, $query) {
         $that->assertEquals('t', $args[0]);
         $that->assertEquals('<', $args[1]);
         $that->assertInternalType('int', $args[2]);
         $diff = time() - $args[2];
         // 2 seconds grace period should be enough
         $that->assertTrue($diff <= 102);
         $that->assertTrue($diff >= 100);
         return $query->reveal();
     });
     $query->order('t')->shouldBeCalledTimes(1)->willReturn($query->reveal());
     $query->keysOnly()->shouldBeCalledTimes(1)->willReturn($query->reveal());
     $query->limit(1000)->shouldBeCalledTimes(1)->willReturn($query->reveal());
     $this->datastore->transaction()->shouldBeCalledTimes(1)->willReturn($this->transaction->reveal());
     $this->datastore->query()->shouldBeCalledTimes(1)->willReturn($query->reveal());
     $this->datastore->runQuery(Argument::type(Query::class), Argument::type('array'))->shouldBeCalledTimes(1)->will(function ($args) use($that, $query, $entity1, $entity2) {
         $that->assertEquals($query->reveal(), $args[0]);
         $that->assertEquals(['namespaceId' => self::NAMESPACE_ID], $args[1]);
         return [$entity1, $entity2];
     });
     $this->datastore->deleteBatch([$key1, $key2])->shouldBeCalledTimes(1)->willThrow(new Exception());
     $datastoreSessionHandler = new DatastoreSessionHandler($this->datastore->reveal(), 1000);
     $datastoreSessionHandler->open(self::NAMESPACE_ID, self::KIND);
     $ret = $datastoreSessionHandler->gc(100);
     $this->assertEquals(false, $ret);
 }
 /**
  * Convert an EntityResult into an array of entities
  *
  * @see https://cloud.google.com/datastore/reference/rest/v1/EntityResult EntityResult
  *
  * @param array $entityResult The EntityResult from a Lookup.
  * @param string|array $class If a string, the name of the class to return results as.
  *        Must be a subclass of {@see Google\Cloud\Datastore\Entity}.
  *        If not set, {@see Google\Cloud\Datastore\Entity} will be used.
  *        If an array is given, it must be an associative array, where
  *        the key is a Kind and the value is the name of a subclass of
  *        {@see Google\Cloud\Datastore\Entity}.
  * @return Entity[]
  */
 private function mapEntityResult(array $entityResult, $class)
 {
     $entities = [];
     foreach ($entityResult as $result) {
         $entity = $result['entity'];
         $properties = [];
         $excludes = [];
         $meanings = [];
         if (isset($entity['properties'])) {
             $res = $this->entityMapper->responseToEntityProperties($entity['properties']);
             $properties = $res['properties'];
             $excludes = $res['excludes'];
             $meanings = $res['meanings'];
         }
         $namespaceId = isset($entity['key']['partitionId']['namespaceId']) ? $entity['key']['partitionId']['namespaceId'] : null;
         $key = new Key($this->projectId, ['path' => $entity['key']['path'], 'namespaceId' => $namespaceId]);
         if (is_array($class)) {
             $lastPathElement = $key->pathEnd();
             if (!array_key_exists($lastPathElement['kind'], $class)) {
                 throw new InvalidArgumentException(sprintf('No class found for kind %s', $lastPathElement['kind']));
             }
             $className = $class[$lastPathElement['kind']];
         } else {
             $className = $class;
         }
         $entities[] = $this->entity($key, $properties, ['cursor' => isset($result['cursor']) ? $result['cursor'] : null, 'baseVersion' => isset($result['version']) ? $result['version'] : null, 'className' => $className, 'populatedByService' => true, 'excludeFromIndexes' => $excludes, 'meanings' => $meanings]);
     }
     return $entities;
 }
Esempio n. 3
0
 public function testSetLastElementIdentifierTypeName()
 {
     $key = new Key('foo', ['path' => [['kind' => 'foo', 'id' => 2], ['kind' => 'foo']]]);
     $key->setLastElementIdentifier(1, Key::TYPE_NAME);
     $this->assertEquals($key->path(), [['kind' => 'foo', 'id' => 2], ['kind' => 'foo', 'name' => 1]]);
 }
Esempio n. 4
0
 /**
  * Use another Key's path as the current Key's ancestor
  *
  * Given key path will be prepended to any path elements on the current key.
  *
  * Example:
  * ```
  * $parent = $datastore->key('Person', 'Dad');
  * $key->ancestorKey($parent);
  * ```
  *
  * @param Key $key The ancestor Key.
  * @return Key
  * @throws InvalidArgumentException
  */
 public function ancestorKey(Key $key)
 {
     if ($key->state() !== self::STATE_NAMED) {
         throw new InvalidArgumentException('Cannot use an incomplete key as an ancestor');
     }
     $path = $key->path();
     $this->path = array_merge($path, $this->path);
     return $this;
 }
Esempio n. 5
0
 public function testPathEndIdentifierTypeNull()
 {
     $key = new Key('foo', ['path' => [['kind' => 'foo', 'id' => 2], ['kind' => 'bar']]]);
     $this->assertNull($key->pathEndIdentifierType());
 }