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