2023-07-10 05:10:28 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class MediaDB
|
|
|
|
{
|
2023-07-11 01:04:51 +00:00
|
|
|
private $handle;
|
2023-07-10 05:10:28 +00:00
|
|
|
private array $lines = [];
|
|
|
|
|
2023-07-10 05:48:40 +00:00
|
|
|
// TODO: create a persist() method that updates the line if the offset where
|
|
|
|
// it originally existed in is given by 'ftell'. If it doesn't have
|
|
|
|
// an ID, then try to find it in the file and if it doesn't exist,
|
|
|
|
// append
|
|
|
|
|
2023-07-10 05:10:28 +00:00
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
// Just initialize the file handler
|
2023-07-11 01:04:51 +00:00
|
|
|
$this->handle = fopen($GLOBALS['path_mediadb'], 'r');
|
|
|
|
if ($this->handle === false)
|
2023-07-10 05:10:28 +00:00
|
|
|
Json::error('Error opening media DB');
|
|
|
|
}
|
|
|
|
|
2023-07-11 01:04:51 +00:00
|
|
|
private function getLine(): ?string
|
2023-07-10 05:10:28 +00:00
|
|
|
{
|
2023-07-11 01:04:51 +00:00
|
|
|
return feof($this->handle) ? null : fgets($this->handle);
|
2023-07-10 05:10:28 +00:00
|
|
|
}
|
|
|
|
|
2023-07-11 01:04:51 +00:00
|
|
|
public static function add(Item $item)
|
2023-07-10 05:48:40 +00:00
|
|
|
{
|
|
|
|
$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());
|
|
|
|
|
2023-07-10 12:14:56 +00:00
|
|
|
if (fwrite($file, $line . "\n") == false)
|
2023-07-10 05:48:40 +00:00
|
|
|
Json::error('Write operation failed on Item adding')->die();
|
|
|
|
|
|
|
|
fclose($file);
|
|
|
|
|
|
|
|
// The $this->list will be updated on trying to find new items
|
|
|
|
}
|
2023-07-10 05:10:28 +00:00
|
|
|
public function map(callable $func)
|
|
|
|
{
|
|
|
|
// First read from what's already in memory
|
2023-07-11 01:04:51 +00:00
|
|
|
foreach ($this->lines as $key => $i_line) {
|
|
|
|
if ($func($i_line, $key) === true) return;
|
2023-07-10 05:10:28 +00:00
|
|
|
}
|
|
|
|
|
2023-07-10 05:48:40 +00:00
|
|
|
// If we run out, read from the file and append to array so the next
|
|
|
|
// lookup is fast
|
2023-07-10 05:10:28 +00:00
|
|
|
while ($line = $this->getLine()) {
|
|
|
|
$this->lines[] = $line;
|
|
|
|
|
2023-07-11 01:04:51 +00:00
|
|
|
// 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;
|
2023-07-10 05:10:28 +00:00
|
|
|
}
|
|
|
|
}
|
2023-07-11 01:04:51 +00:00
|
|
|
|
|
|
|
// ---- 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;
|
|
|
|
}
|
2023-07-10 05:10:28 +00:00
|
|
|
}
|