1*d92c078cSAndreas Gohr<?php 2*d92c078cSAndreas Gohr 3*d92c078cSAndreas Gohrnamespace dokuwiki\Search\Collection; 4*d92c078cSAndreas Gohr 5*d92c078cSAndreas Gohruse dokuwiki\Search\Exception\IndexAccessException; 6*d92c078cSAndreas Gohruse dokuwiki\Search\Exception\IndexLockException; 7*d92c078cSAndreas Gohruse dokuwiki\Search\Exception\IndexWriteException; 8*d92c078cSAndreas Gohr 9*d92c078cSAndreas Gohr/** 10*d92c078cSAndreas Gohr * Abstract collection for direct 1:1 entity-token mappings 11*d92c078cSAndreas Gohr * 12*d92c078cSAndreas Gohr * In a direct collection each entity has exactly one token stored at the entity's position 13*d92c078cSAndreas Gohr * in the token index (entity.RID === token.RID). No frequency or reverse indexes are used. 14*d92c078cSAndreas Gohr * 15*d92c078cSAndreas Gohr * Example: each page has exactly one title. 16*d92c078cSAndreas Gohr * 17*d92c078cSAndreas Gohr * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 18*d92c078cSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 19*d92c078cSAndreas Gohr */ 20*d92c078cSAndreas Gohrabstract class DirectCollection extends AbstractCollection 21*d92c078cSAndreas Gohr{ 22*d92c078cSAndreas Gohr /** 23*d92c078cSAndreas Gohr * Store a single token for the given entity 24*d92c078cSAndreas Gohr * 25*d92c078cSAndreas Gohr * Takes the first token from the list and writes it directly at the entity's position 26*d92c078cSAndreas Gohr * in the token index. An empty list stores an empty string. 27*d92c078cSAndreas Gohr * 28*d92c078cSAndreas Gohr * @param string $entity The name of the entity 29*d92c078cSAndreas Gohr * @param string[] $tokens The list of tokens (only the first is used) 30*d92c078cSAndreas Gohr * @throws IndexLockException 31*d92c078cSAndreas Gohr * @throws IndexAccessException 32*d92c078cSAndreas Gohr * @throws IndexWriteException 33*d92c078cSAndreas Gohr */ 34*d92c078cSAndreas Gohr public function addEntity(string $entity, array $tokens): void 35*d92c078cSAndreas Gohr { 36*d92c078cSAndreas Gohr if (!$this->isWritable) { 37*d92c078cSAndreas Gohr throw new IndexLockException('Indexes not locked. Forgot to call lock()?'); 38*d92c078cSAndreas Gohr } 39*d92c078cSAndreas Gohr 40*d92c078cSAndreas Gohr $entityIndex = $this->getEntityIndex(); 41*d92c078cSAndreas Gohr $entityId = $entityIndex->accessCachedValue($entity); 42*d92c078cSAndreas Gohr 43*d92c078cSAndreas Gohr $token = $tokens[0] ?? ''; 44*d92c078cSAndreas Gohr $tokenIndex = $this->getTokenIndex(''); 45*d92c078cSAndreas Gohr $tokenIndex->changeRow($entityId, $token); 46*d92c078cSAndreas Gohr $tokenIndex->save(); 47*d92c078cSAndreas Gohr } 48*d92c078cSAndreas Gohr 49*d92c078cSAndreas Gohr /** 50*d92c078cSAndreas Gohr * Get the token stored for the given entity 51*d92c078cSAndreas Gohr * 52*d92c078cSAndreas Gohr * @param string $entity The name of the entity 53*d92c078cSAndreas Gohr * @return string The stored token, or empty string if none 54*d92c078cSAndreas Gohr * @throws IndexAccessException 55*d92c078cSAndreas Gohr * @throws IndexLockException 56*d92c078cSAndreas Gohr * @throws IndexWriteException 57*d92c078cSAndreas Gohr */ 58*d92c078cSAndreas Gohr public function getToken(string $entity): string 59*d92c078cSAndreas Gohr { 60*d92c078cSAndreas Gohr $entityIndex = $this->getEntityIndex(); 61*d92c078cSAndreas Gohr $entityId = $entityIndex->accessCachedValue($entity); 62*d92c078cSAndreas Gohr 63*d92c078cSAndreas Gohr $tokenIndex = $this->getTokenIndex(''); 64*d92c078cSAndreas Gohr return $tokenIndex->retrieveRow($entityId); 65*d92c078cSAndreas Gohr } 66*d92c078cSAndreas Gohr 67*d92c078cSAndreas Gohr /** 68*d92c078cSAndreas Gohr * Not actually used, because we override addEntity() to directly write the token. 69*d92c078cSAndreas Gohr * @inheritdoc 70*d92c078cSAndreas Gohr */ 71*d92c078cSAndreas Gohr protected function countTokens(array $tokens): array 72*d92c078cSAndreas Gohr { 73*d92c078cSAndreas Gohr $token = $tokens[0] ?? ''; 74*d92c078cSAndreas Gohr return [$token => 1]; 75*d92c078cSAndreas Gohr } 76*d92c078cSAndreas Gohr} 77