xref: /dokuwiki/inc/Search/Index/MemoryIndex.php (revision 9bd7d62f47cb0e2a7651fefd7106f6ac10625281)
1<?php
2
3namespace dokuwiki\Search\Index;
4
5use dokuwiki\Search\Exception\IndexWriteException;
6
7/**
8 * Access to a single index file
9 *
10 * Access using this class always happens by loading the full index into memory.
11 * All modifications need to be explicitly made permanent using the save() method.
12 * Should be used for small indexes that receive many changes at once.
13 */
14class MemoryIndex extends AbstractIndex
15{
16
17    /** @var string the raw data lines of the index, no newlines */
18    protected $data;
19
20    /**
21     * Loads the full contents of the index into memory
22     *
23     * @inheritdoc
24     */
25    public function __construct($idx, $suffix = '')
26    {
27        parent::__construct($idx, $suffix);
28
29        $this->data = [];
30        if (!file_exists($this->filename)) return;
31        $this->data = file($this->filename, FILE_IGNORE_NEW_LINES);
32
33    }
34
35    /** @inheritdoc */
36    public function changeRow($rid, $value)
37    {
38        if ($rid > count($this->data)) {
39            $this->data = array_pad($this->data, $rid, '');
40        }
41        $this->data[$rid] = $value;
42    }
43
44    /** @inheritdoc */
45    public function retrieveRow($rid)
46    {
47        if (isset($this->data[$rid])) return $this->data[$rid];
48        return '';
49    }
50
51    /**
52     * Save the changed index back to its file
53     *
54     * @throws IndexWriteException
55     */
56    public function save()
57    {
58        global $conf;
59
60        $tempname = $this->filename . '.tmp';
61
62        $fh = @fopen($tempname, 'w');
63        if (!$fh) {
64            throw new IndexWriteException("Failed to write $tempname");
65        }
66        fwrite($fh, implode("\n", $this->data));
67        if (!empty($lines)) {
68            fwrite($fh, "\n");
69        }
70        fclose($fh);
71
72        if ($conf['fperm']) {
73            chmod($tempname, $conf['fperm']);
74        }
75
76        if (!io_rename($tempname, $this->filename)) {
77            throw new IndexWriteException("Failed to write {$this->filename}");
78        }
79    }
80
81}
82