_dbFile = $dbPath . '/pages.db'; // DEBUG: Uncomment the line below if it still fails, to see where it is trying to write // file_put_contents('php://stderr', "Writing DB to: " . $this->_dbFile . "\n"); $this->_initDb(); } /** * Connect to SQLite and ensure the table exists */ private function _initDb(): void { try { $this->_db = new PDO("sqlite:" . $this->_dbFile); $this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Create the table if it doesn't exist $sql = "CREATE TABLE IF NOT EXISTS pages ( page TEXT, title TEXT, title_text TEXT, hid TEXT, crc INTEGER PRIMARY KEY )"; $this->_db->exec($sql); // Optimization for SQLite $this->_db->exec("PRAGMA journal_mode = WAL"); $this->_db->exec("PRAGMA synchronous = NORMAL"); } catch (PDOException $e) { die("Database Error: " . $e->getMessage()); } } /** * Add or Update a page mapping */ public function add(string $page, string $title, string $title_text = '', string $hid = ''): void { $crc = sprintf('%u', crc32($page . $hid) ?: 1); $sql = "REPLACE INTO pages (page, title, title_text, hid, crc) VALUES (:page, :title, :title_text, :hid, :crc)"; try { $stmt = $this->_db->prepare($sql); $stmt->bindValue(':page', $page); $stmt->bindValue(':title', $title); $stmt->bindValue(':title_text', $title_text); $stmt->bindValue(':hid', $hid); $stmt->bindValue(':crc', $crc); $stmt->execute(); } catch (PDOException $e) { // Ignore write errors during indexing to keep stream alive } } /** * Retrieve mapping by CRC */ public function getByCrc(array $crcs): array { if (empty($crcs)) return []; $placeholders = implode(',', array_fill(0, count($crcs), '?')); $sql = "SELECT * FROM pages WHERE crc IN ($placeholders)"; try { $stmt = $this->_db->prepare($sql); $stmt->execute(array_values($crcs)); $results = []; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $results[$row['crc']] = $row; } return $results; } catch (PDOException $e) { return []; } } }