handle = fopen($GLOBALS['path_mediadb'], 'r'); if ($this->handle === false) Json::error('Error opening media DB'); } private function getLine(): ?string { return feof($this->handle) ? null : fgets($this->handle); } public static function add(Item $item) { $file = fopen($GLOBALS['path_mediadb'], 'a+'); if ($file === false) Json::error('Failed opening media DB for adding new Item')->die(); $line = $item->getHash() . ' ' . implode(' ', $item->getTags()); if (fwrite($file, $line . "\n") == false) Json::error('Write operation failed on Item adding')->die(); fclose($file); // The $this->list will be updated on trying to find new items } public function map(callable $func) { // First read from what's already in memory foreach ($this->lines as $key => $i_line) { if ($func($i_line, $key) === true) return; } // If we run out, read from the file and append to array so the next // lookup is fast while ($line = $this->getLine()) { $this->lines[] = $line; // NOTE: We are kinda assuming that the keys are autoincrementing // unsigned integers... I think it should be fine, but o_0 $key = count($this->lines) - 1; if ($func($line, $key) === true) return; } } // ---- ITEM OPERATIONS ---- public function loadItem(string $id): ?Item { $key = $this->searchItem($id); if ($key === null) return null; return Item::fromLine($this->lines[$key]); } private function searchItem(string $id): ?int { $ret = null; $this->map(function ($line, $key) use (&$ret, $id) { $item = Item::fromLine($line); if ($item->getHash() == $id) { $ret = $key; return true; } return false; }); return $ret; } }