diff --git a/phpdotnet/phd/Format.php b/phpdotnet/phd/Format.php index 2317deba..72f70548 100644 --- a/phpdotnet/phd/Format.php +++ b/phpdotnet/phd/Format.php @@ -24,7 +24,7 @@ abstract class Format extends ObjectStorage private $elementmap = array(); private $textmap = array(); private $formatname = "UNKNOWN"; - protected $sqlite; + private IndexRepository $indexRepository; protected $title; protected $fp = array(); @@ -63,16 +63,12 @@ abstract class Format extends ObjectStorage protected $CURRENT_ID = ""; public function __construct() { - $sqlite = Config::indexcache(); - if (!$sqlite) { - if (file_exists(Config::output_dir() . "index.sqlite")) { - $sqlite = new \SQLite3(Config::output_dir() . 'index.sqlite'); + if (Config::indexcache()) { + $this->indexRepository = Config::indexcache(); + if (!($this instanceof Index)) { + $this->sortIDs(); } } - if ($sqlite) { - $this->sqlite = $sqlite; - $this->sortIDs(); - } } abstract public function transformFromMap($open, $tag, $name, $attrs, $props); @@ -146,18 +142,12 @@ public function getPIHandler($target) { } public function sortIDs() { - $this->sqlite->createAggregate("indexes", array($this, "SQLiteIndex"), array($this, "SQLiteFinal"), 9); - $this->sqlite->createAggregate("children", array($this, "SQLiteChildren"), array($this, "SQLiteFinal"), 2); - $this->sqlite->createAggregate("refname", array($this, "SQLiteRefname"), array($this, "SQLiteFinal"), 2); - $this->sqlite->createAggregate("varname", array($this, "SQLiteVarname"), array($this, "SQLiteFinal"), 2); - $this->sqlite->createAggregate("classname", array($this, "SQLiteClassname"), array($this, "SQLiteFinal"), 2); - $this->sqlite->createAggregate("example", array($this, "SQLiteExample"), array($this, "SQLiteFinal"), 1); - $this->sqlite->query('SELECT indexes(docbook_id, filename, parent_id, sdesc, ldesc, element, previous, next, chunk) FROM ids'); - $this->sqlite->query('SELECT children(docbook_id, parent_id) FROM ids WHERE chunk != 0'); - $this->sqlite->query('SELECT refname(docbook_id, sdesc) FROM ids WHERE element=\'refentry\''); - $this->sqlite->query('SELECT varname(docbook_id, sdesc) FROM ids WHERE element=\'phpdoc:varentry\''); - $this->sqlite->query('SELECT classname(docbook_id, sdesc) FROM ids WHERE element=\'phpdoc:exceptionref\' OR element=\'phpdoc:classref\''); - $this->sqlite->query('SELECT example(docbook_id) FROM ids WHERE element=\'example\''); + $this->indexes = $this->indexRepository->getIndexes(); + $this->children = $this->indexRepository->getChildren(); + $this->refs = $this->indexRepository->getRefNames(); + $this->vars = $this->indexRepository->getVarNames(); + $this->classes = $this->indexRepository->getClassNames(); + $this->examples = $this->indexRepository->getExamples(); } public function SQLiteIndex($context, $index, $id, $filename, $parent, $sdesc, $ldesc, $element, $previous, $next, $chunk) { @@ -174,36 +164,6 @@ public function SQLiteIndex($context, $index, $id, $filename, $parent, $sdesc, $ ); } - public function SQLiteChildren($context, $index, $id, $parent) - { - if (!isset($this->children[$parent]) - || !is_array($this->children[$parent]) - ) { - $this->children[$parent] = array(); - } - $this->children[$parent][] = $id; - } - - public function SQLiteRefname($context, $index, $id, $sdesc) { - $ref = strtolower(str_replace(array("_", "::", "->"), array("-", "-", "-"), html_entity_decode($sdesc, ENT_QUOTES, 'UTF-8'))); - $this->refs[$ref] = $id; - } - - public function SQLiteVarname($context, $index, $id, $sdesc) { - $this->vars[$sdesc] = $id; - } - - public function SQLiteClassname($context, $index, $id, $sdesc) { - $this->classes[strtolower($sdesc)] = $id; - } - public function SQLiteExample($context, $index, $id) { - $this->examples[] = $id; - } - - public static function SQLiteFinal($context) { - return $context; - } - /** * Calls update(). * @@ -295,31 +255,10 @@ public function addVarname($id, $var) { $this->vars[$var] = $id; } public function getChangelogsForChildrenOf($bookids) { - $ids = array(); - foreach((array)$bookids as $bookid) { - $ids[] = "'" . $this->sqlite->escapeString($bookid) . "'"; - } - $results = $this->sqlite->query("SELECT * FROM changelogs WHERE parent_id IN (" . join(", ", $ids) . ")"); - return $this->_returnChangelog($results); + return $this->indexRepository->getChangelogsForChildrenOf($bookids); } public function getChangelogsForMembershipOf($memberships) { - $ids = array(); - foreach((array)$memberships as $membership) { - $ids[] = "'" . $this->sqlite->escapeString($membership) . "'"; - } - $results = $this->sqlite->query("SELECT * FROM changelogs WHERE membership IN (" . join(", ", $ids) . ")"); - return $this->_returnChangelog($results); - } - public function _returnChangelog($results) { - if (!$results) { - return array(); - } - - $changelogs = array(); - while ($row = $results->fetchArray()) { - $changelogs[] = $row; - } - return $changelogs; + return $this->indexRepository->getChangelogsForMembershipOf($memberships); } public function getRefs() { return $this->refs; @@ -490,7 +429,7 @@ final public function isChunkID($id) final public function getRootIndex() { static $root = null; if ($root == null) { - $root = $this->sqlite->querySingle('SELECT * FROM ids WHERE parent_id=""', true); + $root = $this->indexRepository->getRootIndex(); } return $root; } diff --git a/phpdotnet/phd/IndexRepository.php b/phpdotnet/phd/IndexRepository.php index 24758006..90177213 100644 --- a/phpdotnet/phd/IndexRepository.php +++ b/phpdotnet/phd/IndexRepository.php @@ -3,6 +3,13 @@ class IndexRepository { + private array $indexes = []; + private array $children = []; + private array $refs = []; + private array $vars = []; + private array $classes = []; + private array $examples = []; + public function __construct( private \SQLite3 $db ) {} @@ -116,4 +123,162 @@ public function lastErrorCode(): int { public function lastErrorMsg(): string { return $this->db->lastErrorMsg(); } + + public function getIndexingTimeCount(): int { + $queryResult = $this->db->query('SELECT COUNT(time) FROM indexing'); + if ($queryResult === false) { + return 0; + } + $indexingCount = $queryResult->fetchArray(\SQLITE3_NUM); + return $indexingCount[0]; + } + + public function getIndexingTime(): int { + $indexing = $this->db->query('SELECT time FROM indexing') + ->fetchArray(\SQLITE3_ASSOC); + return $indexing['time']; + } + + public function getIndexes(): array { + $this->indexes = []; + $this->db->createAggregate("indexes", [$this, "SQLiteIndex"], [$this, "SQLiteFinal"], 9); + $this->db->query('SELECT indexes(docbook_id, filename, parent_id, sdesc, ldesc, element, previous, next, chunk) FROM ids'); + return $this->indexes; + } + + protected function SQLiteIndex($context, $index, $id, $filename, $parent, $sdesc, $ldesc, $element, $previous, $next, $chunk): void { + $this->indexes[$id] = [ + "docbook_id" => $id, + "filename" => $filename, + "parent_id" => $parent, + "sdesc" => $sdesc, + "ldesc" => $ldesc, + "element" => $element, + "previous" => $previous, + "next" => $next, + "chunk" => $chunk, + ]; + } + + private static function SQLiteFinal($context): mixed { + return $context; + } + + public function getChildren(): array { + $this->children = []; + $this->db->createAggregate("children", [$this, "SQLiteChildren"], [$this, "SQLiteFinal"], 2); + $this->db->query('SELECT children(docbook_id, parent_id) FROM ids WHERE chunk != 0'); + return $this->children; + } + + private function SQLiteChildren($context, $index, $id, $parent): void { + if (!isset($this->children[$parent]) + || !is_array($this->children[$parent]) + ) { + $this->children[$parent] = []; + } + $this->children[$parent][] = $id; + } + + public function getRefNames(): array { + $this->refs = []; + $this->db->createAggregate("refname", [$this, "SQLiteRefname"], [$this, "SQLiteFinal"], 2); + $this->db->query('SELECT refname(docbook_id, sdesc) FROM ids WHERE element=\'refentry\''); + return $this->refs; + } + + + private function SQLiteRefname($context, $index, $id, $sdesc): void { + $ref = strtolower( + str_replace( + ["_", "::", "->"], + ["-", "-", "-"], + html_entity_decode($sdesc, ENT_QUOTES, 'UTF-8') + ) + ); + $this->refs[$ref] = $id; + } + + public function getVarNames(): array { + $this->vars = []; + $this->db->createAggregate("varname", [$this, "SQLiteVarname"], [$this, "SQLiteFinal"], 2); + $this->db->query('SELECT varname(docbook_id, sdesc) FROM ids WHERE element=\'phpdoc:varentry\''); + return $this->vars; + } + + private function SQLiteVarname($context, $index, $id, $sdesc): void { + $this->vars[$sdesc] = $id; + } + + public function getClassNames(): array { + $this->classes = []; + $this->db->createAggregate("classname", [$this, "SQLiteClassname"], [$this, "SQLiteFinal"], 2); + $this->db->query('SELECT classname(docbook_id, sdesc) FROM ids WHERE element=\'phpdoc:exceptionref\' OR element=\'phpdoc:classref\''); + return $this->classes; + } + + private function SQLiteClassname($context, $index, $id, $sdesc): void { + $this->classes[strtolower($sdesc)] = $id; + } + + public function getExamples(): array { + $this->examples = []; + $this->db->createAggregate("example", [$this, "SQLiteExample"], [$this, "SQLiteFinal"], 1); + $this->db->query('SELECT example(docbook_id) FROM ids WHERE element=\'example\''); + return $this->examples; + } + + private function SQLiteExample($context, $index, $id): void { + $this->examples[] = $id; + } + + public function getRootIndex(): array|false { + return $this->db->querySingle('SELECT * FROM ids WHERE parent_id=""', true); + } + + public function getChangelogsForChildrenOf($bookids): array { + $ids = []; + foreach((array)$bookids as $bookid) { + $ids[] = "'" . $this->db->escapeString($bookid) . "'"; + } + $results = $this->db->query("SELECT * FROM changelogs WHERE parent_id IN (" . join(", ", $ids) . ")"); + return $this->_returnChangelog($results); + } + + public function getChangelogsForMembershipOf($memberships): array { + $ids = []; + foreach((array)$memberships as $membership) { + $ids[] = "'" . $this->db->escapeString($membership) . "'"; + } + $results = $this->db->query("SELECT * FROM changelogs WHERE membership IN (" . join(", ", $ids) . ")"); + return $this->_returnChangelog($results); + } + + private function _returnChangelog($results): array { + if (!$results) { + return []; + } + + $changelogs = []; + while ($row = $results->fetchArray()) { + $changelogs[] = $row; + } + return $changelogs; + } + + public function getParents(array $renderIds): array { + $parents = []; + foreach($renderIds as $p => $v) { + do { + $id = $this->db->escapeString($p); + $row = $this->db->query("SELECT parent_id FROM ids WHERE docbook_id = '$id'")->fetchArray(\SQLITE3_ASSOC); + if ($row["parent_id"]) { + $parents[] = $p = $row["parent_id"]; + continue; + } + break; + } while(1); + } + return $parents; + } } diff --git a/phpdotnet/phd/functions.php b/phpdotnet/phd/functions.php index 013d2d2d..19e7af8f 100644 --- a/phpdotnet/phd/functions.php +++ b/phpdotnet/phd/functions.php @@ -211,19 +211,12 @@ function requireIndexing(Config $config, ?\SQLite3 $db = null): bool { return true; } - if ($db === null) { - $db = new \SQLite3($indexfile); - } - $indexingCount = $db->query('SELECT COUNT(time) FROM indexing') - ->fetchArray(SQLITE3_NUM); - if ($indexingCount[0] == 0) { + if ($config->indexcache()->getIndexingTimeCount() === 0) { return true; } - $indexing = $db->query('SELECT time FROM indexing') - ->fetchArray(SQLITE3_ASSOC); $xmlLastModification = filemtime($config->xml_file()); - if ($indexing['time'] > $xmlLastModification) { + if ($config->indexcache()->getIndexingTime() > $xmlLastModification) { return false; } return true; diff --git a/render.php b/render.php index 4dfb2ae1..c8315511 100644 --- a/render.php +++ b/render.php @@ -75,30 +75,18 @@ function make_reader() { //Partial Rendering - $idlist = Config::render_ids() + Config::skip_ids(); + $idlist = $config->render_ids() + $config->skip_ids(); if (!empty($idlist)) { v("Running partial build", VERBOSE_RENDER_STYLE); $parents = []; - if (file_exists(Config::output_dir() . "index.sqlite")) { - $sqlite = new \SQLite3(Config::output_dir() . "index.sqlite"); - // Fetch all ancestors of the ids we should render - foreach(Config::render_ids() as $p => $v) { - do { - $id = $sqlite->escapeString($p); - $row = $sqlite->query("SELECT parent_id FROM ids WHERE docbook_id = '$id'")->fetchArray(SQLITE3_ASSOC); - if ($row["parent_id"]) { - $parents[] = $p = $row["parent_id"]; - continue; - } - break; - } while(1); - } + if ($config->indexcache()) { + $parents = $config->indexcache()->getParents($config->render_ids()); } $reader = new Reader_Partial( - Config::render_ids(), - Config::skip_ids(), + $config->render_ids(), + $config->skip_ids(), $parents ); } else { @@ -116,23 +104,25 @@ function make_reader() { $readerOpts |= LIBXML_XINCLUDE; } -if (file_exists(Config::output_dir() . 'index.sqlite')) { - $db = new \SQLite3(Config::output_dir() . 'index.sqlite'); +if (Config::memoryindex()) { + $db = new \SQLite3(":memory:"); + $initializeDb = true; } else { - $db = null; + $initializeDb = !file_exists(Config::output_dir() . 'index.sqlite'); + $db = new \SQLite3(Config::output_dir() . 'index.sqlite'); +} +$indexRepository = new IndexRepository($db); +if ($initializeDb) { + $indexRepository->init(); } +Config::set_indexcache($indexRepository); // Indexing if (requireIndexing(new Config, $db)) { v("Indexing...", VERBOSE_INDEXING); - if (Config::memoryindex()) { - $db = new \SQLite3(":memory:"); - } else { - $db = $db ?? new \SQLite3(Config::output_dir() . 'index.sqlite'); - } + Config::indexcache()->init(); // Create indexer - $indexRepository = new IndexRepository($db); - $format = new Index($indexRepository); + $format = new Index(Config::indexcache()); $render->attach($format); $reader = make_reader();