public function canAnswer(array $keys, array $options) { if (!parent::canAnswer($keys, $options)) { return false; } if (isset($options['sort'], $options['order'])) { return ObjectManager::makeArray($options['sort']) === $this->options['sort'] && strtoupper($options['order']) === $this->options['order']; } return true; }
/** * Fetch a node and all its descendants. Children are returned in the * same order they were inserted. * * @param UUID|UUID[] $roots * @return array Multi-dimensional tree. The top level is a map from the uuid of a node * to attributes about that node. The top level contains not just the parents, but all nodes * within this tree. Within each node there is a 'children' key that contains a map from * the child uuid's to references back to the top level of this identity map. As such this * result can be read either as a list or a tree. * @throws DataModelException When invalid data is received from self::fetchSubtreeNodeList */ public function fetchSubtreeIdentityMap($roots) { $roots = ObjectManager::makeArray($roots); if (!$roots) { return array(); } $nodes = $this->fetchSubtreeNodeList($roots); if (!$nodes) { throw new DataModelException('subtree node list should have at least returned root: ' . $root, 'process-data'); } elseif (count($nodes) === 1) { $parentMap = $this->fetchParentMap(reset($nodes)); } else { $parentMap = $this->fetchParentMap(call_user_func_array('array_merge', $nodes)); } $identityMap = array(); foreach ($parentMap as $child => $parent) { if (!array_key_exists($child, $identityMap)) { $identityMap[$child] = array('children' => array()); } // Root nodes have no parent if ($parent !== null) { $identityMap[$parent->getAlphadecimal()]['children'][$child] =& $identityMap[$child]; } } foreach (array_keys($identityMap) as $parent) { ksort($identityMap[$parent]['children']); } return $identityMap; }
/** * Takes an array of rows going to/from the database/cache. Converts uuid and * things that look like uuids into the requested format. * * @param array $array * @param string $format * @return string[]|UUIDBlob[] Typically an array of strings. If required by the database when * $format === 'binary' uuid values will be represented as Blob objects. */ public static function convertUUIDs($array, $format = 'binary') { $array = ObjectManager::makeArray($array); foreach ($array as $key => $value) { if ($value instanceof UUIDBlob) { // database encoded binary value if ($format === 'alphadecimal') { $array[$key] = UUID::create($value->fetch())->getAlphadecimal(); } } elseif ($value instanceof UUID) { if ($format === 'binary') { $array[$key] = $value->getBinary(); } elseif ($format === 'alphadecimal') { $array[$key] = $value->getAlphadecimal(); } } elseif (is_string($value) && substr($key, -3) === '_id') { // things that look like uuids $len = strlen($value); if ($format === 'alphadecimal' && $len === self::BIN_LEN) { $array[$key] = UUID::create($value)->getAlphadecimal(); } elseif ($format === 'binary' && ($len >= self::MIN_ALNUM_LEN && $len <= self::ALNUM_LEN || $len === self::HEX_LEN)) { // Note that if a value is a binary string, but needs to be encoded // for the database, that is unhandled here. A patch is under // consideration to allow binary data to always be wrapped in a Blob // to clear up this inconsistency. $array[$key] = UUID::create($value)->getBinary(); } } } return $array; }
/** * Returns a boolean true/false if the getMulti()-operation for the given * attributes has already been resolves and doesn't need to query any * outside cache/database. * Determining if a find() has not yet been resolved may be useful so that * additional data may be loaded at once. * * @param array $objectIds Ids to getMulti() * @return bool */ public function gotMulti(array $objectIds) { if (!$objectIds) { return true; } $primaryKey = $this->storage->getPrimaryKeyColumns(); $queries = array(); foreach ($objectIds as $id) { $query = array_combine($primaryKey, ObjectManager::makeArray($id)); $query = UUID::convertUUIDs($query, 'alphadecimal'); if (!$this->mapper->get($query)) { $queries[] = $query; } } if ($queries && $this->mapper instanceof Mapper\CachingObjectMapper) { return false; } return $this->foundMulti($queries); }