Skip to content

Commit

Permalink
Inject database dependency into constructor of Index
Browse files Browse the repository at this point in the history
Add new IndexRepository class to handle all database access.
Inject IndexRepository as a dependency into the constructor of Index and use that instead of directly accessing the database.
Add basic indexing test.
Fix existing test that uses indexing to use IndexRepository.
  • Loading branch information
haszi committed Mar 28, 2024
1 parent e89427b commit 9052457
Show file tree
Hide file tree
Showing 6 changed files with 368 additions and 112 deletions.
151 changes: 41 additions & 110 deletions phpdotnet/phd/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,14 @@ class Index extends Format
'phpdoc' => 'PI_PHPDOCHandler',
);

private $db;
private IndexRepository $indexRepository;
private $currentchunk;
private $ids = array();
private $currentid;
private $chunks = array();
private $isChunk = array();
protected $nfo = array();
private $isSectionChunk = array();
private $log = '';
private $previousId = "";
private $inChangelog = false;
private $currentChangelog = array();
Expand All @@ -101,6 +100,11 @@ class Index extends Format
private $POST_REPLACEMENT_INDEXES = array();
private $POST_REPLACEMENT_VALUES = array();

public function __construct(IndexRepository $indexRepository) {
$this->indexRepository = $indexRepository;
parent::__construct();
}

public function transformFromMap($open, $tag, $name, $attrs, $props) {
}
public function TEXT($value) {
Expand Down Expand Up @@ -128,58 +132,24 @@ public function update($event, $value = null)
break;
case Render::INIT:
if ($value) {
if (Config::memoryindex()) {
$db = new \SQLite3(":memory:");
} else {
$db = new \SQLite3(Config::output_dir() . 'index.sqlite');
$db->exec('DROP TABLE IF EXISTS ids');
$db->exec('DROP TABLE IF EXISTS indexing');
$db->exec('DROP TABLE IF EXISTS changelogs');
}

$create = <<<SQL
CREATE TABLE ids (
docbook_id TEXT,
filename TEXT,
parent_id TEXT,
sdesc TEXT,
ldesc TEXT,
element TEXT,
previous TEXT,
next TEXT,
chunk INTEGER
);
CREATE TABLE changelogs (
membership TEXT, -- How the extension in distributed (pecl, core, bundled with/out external dependencies..)
docbook_id TEXT,
parent_id TEXT,
version TEXT,
description TEXT
);
CREATE TABLE indexing (
time INTEGER PRIMARY KEY
);
SQL;
$db->exec('PRAGMA default_synchronous=OFF');
$db->exec('PRAGMA count_changes=OFF');
$db->exec('PRAGMA cache_size=100000');
$db->exec($create);

if (Config::memoryindex()) {
Config::set_indexcache($db);
}

$this->db = $db;
$this->indexRepository->init();
$this->chunks = array();
} else {
print_r($this->chunks);
}
break;
case Render::FINALIZE:
$retval = $this->db->exec("BEGIN TRANSACTION; INSERT INTO indexing (time) VALUES ('" . time() . "'); COMMIT");
$this->commit();
if ($this->db->lastErrorCode()) {
trigger_error($this->db->lastErrorMsg(), E_USER_WARNING);
$this->indexRepository->saveIndexingTime(time());
if ($this->indexRepository->commit(
$this->commit,
$this->POST_REPLACEMENT_INDEXES,
$this->POST_REPLACEMENT_VALUES,
$this->changelog,
)) {
$this->commit = [];
}
if ($this->indexRepository->lastErrorCode()) {
trigger_error($this->indexRepository->lastErrorMsg(), E_USER_WARNING);
}
break;
}
Expand Down Expand Up @@ -222,7 +192,7 @@ protected function storeInfo($elm, $id, $filename, $isChunk = true) {
);
// Append "next" to the previously inserted row
if ($isChunk) {
$this->POST_REPLACEMENT_VALUES[$this->previousId] = $this->db->escapeString($id);
$this->POST_REPLACEMENT_VALUES[$this->previousId] = $id;
$this->previousId = $id;
}
}
Expand All @@ -241,34 +211,33 @@ public function appendID() {
$sdesc = $lastChunk["sdesc"];
}

$this->commit[++$idx] = sprintf(
"INSERT INTO ids (docbook_id, filename, parent_id, sdesc, ldesc, element, previous, next, chunk) VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d);\n",
$this->db->escapeString($lastChunkId),
$this->db->escapeString($lastChunk["filename"]),
$this->db->escapeString($this->currentchunk),
$this->db->escapeString($sdesc),
$this->db->escapeString($lastChunk["ldesc"]),
$this->db->escapeString($lastChunk["element"]),
$this->db->escapeString($lastChunk["previous"]),
$this->db->escapeString($lastChunk["chunk"] ? "POST-REPLACEMENT" : ""),
$this->db->escapeString($lastChunk["chunk"])
);
$this->commit[++$idx] = [
"docbook_id" => $lastChunkId,
"filename" => $lastChunk["filename"],
"parent_id" => $this->currentchunk,
"sdesc" => $sdesc,
"ldesc" => $lastChunk["ldesc"],
"element" => $lastChunk["element"],
"previous" => $lastChunk["previous"],
"next" => ($lastChunk["chunk"] ? "POST-REPLACEMENT" : ""),
"chunk" => $lastChunk["chunk"],
];
if ($lastChunk["chunk"]) {
$this->POST_REPLACEMENT_INDEXES[] = array("docbook_id" => $lastChunkId, "idx" => $idx);
}
if ($array === true) {
foreach($lastChunk["sdesc"] as $sdesc) {
$this->commit[++$idx] = sprintf(
"INSERT INTO ids (docbook_id, filename, parent_id, sdesc, ldesc, element, previous, next, chunk) VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0);\n",
$this->db->escapeString($lastChunkId),
$this->db->escapeString($lastChunk["filename"]),
$this->db->escapeString($this->currentchunk),
$this->db->escapeString($sdesc),
$this->db->escapeString($lastChunk["ldesc"]),
$this->db->escapeString($lastChunk["element"]),
$this->db->escapeString($lastChunk["previous"]),
$this->db->escapeString($lastChunk["chunk"] ? "POST-REPLACEMENT" : "")
);
$this->commit[++$idx] = [
"docbook_id" => $lastChunkId,
"filename" => $lastChunk["filename"],
"parent_id" => $this->currentchunk,
"sdesc" => $sdesc,
"ldesc" => $lastChunk["ldesc"],
"element" => $lastChunk["element"],
"previous" => $lastChunk["previous"],
"next" => ($lastChunk["chunk"] ? "POST-REPLACEMENT" : ""),
"chunk" => 0,
];
$this->POST_REPLACEMENT_INDEXES[] = array("docbook_id" => $lastChunkId, "idx" => $idx);
}
}
Expand Down Expand Up @@ -431,44 +400,6 @@ public function format_row($open, $name, $attrs, $props) {
}
}



public function commit() {
if (isset($this->commit) && $this->commit) {
$search = $this->db->escapeString("POST-REPLACEMENT");
$none = $this->db->escapeString("");

foreach($this->POST_REPLACEMENT_INDEXES as $a) {
if (isset($this->POST_REPLACEMENT_VALUES[$a["docbook_id"]])) {
$replacement = $this->POST_REPLACEMENT_VALUES[$a["docbook_id"]];
$this->commit[$a["idx"]] = str_replace($search, $replacement, $this->commit[$a["idx"]]);
} else {
// If there are still post replacement, then they don't have
// any 'next' page
$this->commit[$a["idx"]] = str_replace($search, $none, $this->commit[$a["idx"]]);
}
}

$this->db->exec('BEGIN TRANSACTION; '.implode("", $this->commit).' COMMIT');
$log = "";
foreach($this->changelog as $id => $arr) {
foreach($arr as $entry) {
$log .= sprintf(
"INSERT INTO changelogs (membership, docbook_id, parent_id, version, description) VALUES('%s', '%s', '%s', '%s', '%s');\n",
$this->db->escapeString($entry[0] ?? ''),
$this->db->escapeString($id),
$this->db->escapeString($entry[1]),
$this->db->escapeString($entry[2]),
$this->db->escapeString($entry[3])
);
}
}
$this->db->exec('BEGIN TRANSACTION; ' . $log. ' COMMIT');
$this->log = "";
$this->commit = array();
}
}

public function processFilename() {
static $dbhtml = null;
if ($dbhtml == null) {
Expand Down
119 changes: 119 additions & 0 deletions phpdotnet/phd/IndexRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
namespace phpdotnet\phd;

class IndexRepository
{
public function __construct(
private \SQLite3 $db
) {}

public function init(): void {
$create = <<<SQL
CREATE TABLE ids (
docbook_id TEXT,
filename TEXT,
parent_id TEXT,
sdesc TEXT,
ldesc TEXT,
element TEXT,
previous TEXT,
next TEXT,
chunk INTEGER
);
CREATE TABLE changelogs (
membership TEXT, -- How the extension in distributed (pecl, core, bundled with/out external dependencies..)
docbook_id TEXT,
parent_id TEXT,
version TEXT,
description TEXT
);
CREATE TABLE indexing (
time INTEGER PRIMARY KEY
);
SQL;
$this->db->exec('DROP TABLE IF EXISTS ids');
$this->db->exec('DROP TABLE IF EXISTS indexing');
$this->db->exec('DROP TABLE IF EXISTS changelogs');
$this->db->exec('PRAGMA default_synchronous=OFF');
$this->db->exec('PRAGMA count_changes=OFF');
$this->db->exec('PRAGMA cache_size=100000');
$this->db->exec($create);
}

public function saveIndexingTime(int $time): void {
$this->db->exec("BEGIN TRANSACTION; INSERT INTO indexing (time) VALUES ('" . $time . "'); COMMIT");
}

public function commit(
array $commitList,
array $postReplacementIndexes,
array $postReplacementValues,
array $changelog,
): bool {
if (!$commitList) {
return false;
}

foreach ($postReplacementValues as $key => $postReplacementValue) {
$postReplacementValues[$key] = $this->db->escapeString($postReplacementValue);
}

foreach ($commitList as $key => $commit) {
$commitList[$key] = sprintf(
"INSERT INTO ids (docbook_id, filename, parent_id, sdesc, ldesc, element, previous, next, chunk) VALUES('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d);\n",
$this->db->escapeString($commit["docbook_id"]),
$this->db->escapeString($commit["filename"]),
$this->db->escapeString($commit["parent_id"]),
$this->db->escapeString($commit["sdesc"]),
$this->db->escapeString($commit["ldesc"]),
$this->db->escapeString($commit["element"]),
$this->db->escapeString($commit["previous"]),
$this->db->escapeString($commit["next"]),
$this->db->escapeString($commit["chunk"])
);
}

$search = $this->db->escapeString("POST-REPLACEMENT");
$none = $this->db->escapeString("");

foreach($postReplacementIndexes as $a) {
if (isset($postReplacementValues[$a["docbook_id"]])) {
$replacement = $postReplacementValues[$a["docbook_id"]];
$commitList[$a["idx"]] = str_replace($search, $replacement, $commitList[$a["idx"]]);
} else {
// If there are still post replacement, then they don't have
// any 'next' page
$commitList[$a["idx"]] = str_replace($search, $none, $commitList[$a["idx"]]);
}
}

$this->db->exec('BEGIN TRANSACTION; '.implode("", $commitList).' COMMIT');
$this->saveChangelogs($changelog);
return true;
}

private function saveChangelogs(array $changelog): void {
$log = "";
foreach($changelog as $id => $arr) {
foreach($arr as $entry) {
$log .= sprintf(
"INSERT INTO changelogs (membership, docbook_id, parent_id, version, description) VALUES('%s', '%s', '%s', '%s', '%s');\n",
$this->db->escapeString($entry[0] ?? ''),
$this->db->escapeString($id),
$this->db->escapeString($entry[1]),
$this->db->escapeString($entry[2]),
$this->db->escapeString($entry[3])
);
}
}
$this->db->exec('BEGIN TRANSACTION; ' . $log. ' COMMIT');
}

public function lastErrorCode(): int {
return $this->db->lastErrorCode();
}

public function lastErrorMsg(): string {
return $this->db->lastErrorMsg();
}
}
12 changes: 11 additions & 1 deletion render.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,23 @@ function make_reader() {
// 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');
}
// Create indexer
$format = new Index;
$indexRepository = new IndexRepository($db);
$format = new Index($indexRepository);
$render->attach($format);

$reader->open(Config::xml_file(), NULL, $readerOpts);
$render->execute($reader);

if (Config::memoryindex()) {
Config::set_indexcache($db);
}

$render->detach($format);

v("Indexing done", VERBOSE_INDEXING);
Expand Down
10 changes: 9 additions & 1 deletion tests/index/bug_GH-98.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ Config::init([
"xml_file" => $xml_file,
]);

$index = new TestIndex;
$indexRepository = new IndexRepository(new \SQLite3(
Config::output_dir() . 'index.sqlite',
\SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE
));
$indexRepository->init();

$index = new TestIndex($indexRepository);
$render = new TestRender(new Reader, new Config, null, $index);

$render->run();
Expand All @@ -27,6 +33,8 @@ var_dump(in_array("another.non-chunked.element.id", $indexes));
var_dump(in_array("chunked.element.id", $indexes));
var_dump(in_array("another.chunked.element.id", $indexes));
var_dump(in_array("bug-GH-98", $indexes));

unlink(Config::output_dir() . 'index.sqlite');
?>
--EXPECT--
Indexes stored:
Expand Down
Loading

0 comments on commit 9052457

Please sign in to comment.