Skip to content

Commit

Permalink
Move all database access to IndexRepository
Browse files Browse the repository at this point in the history
Move all database access to IndexRepository.
Use the same database during the entire indexing-rendering process.
Add a simple smoke test for render.php.
  • Loading branch information
haszi committed May 14, 2024
1 parent b535eeb commit e011771
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 121 deletions.
89 changes: 14 additions & 75 deletions phpdotnet/phd/Format.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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().
*
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
165 changes: 165 additions & 0 deletions phpdotnet/phd/IndexRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
) {}
Expand Down Expand Up @@ -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;
}
}
15 changes: 4 additions & 11 deletions phpdotnet/phd/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ function errh($errno, $msg, $file, $line, $ctx = null) {
*
* @return boolean True if indexing is required.
*/
function requireIndexing(Config $config, ?\SQLite3 $db = null): bool {
if ($db === null) {
function requireIndexing(Config $config): bool {
if (! $config->indexcache()) {
$indexfile = $config->output_dir() . 'index.sqlite';
if (!file_exists($indexfile)) {
return true;
Expand All @@ -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;
Expand Down
Loading

0 comments on commit e011771

Please sign in to comment.