*/ declare(strict_types = 1); /** * Class for keeping the persinst fulltext index in sync. */ final class NodaPersinstFulltextSync { /** @var MDMysqli */ private MDMysqli $_mysqli_noda; /** * Removes the obsolete entries. * * @return void */ public function removeObsolete():void { $result = $this->_mysqli_noda->do_read_query("SELECT 1 FROM `persinst_fulltext` WHERE `persinst_fulltext`.`persinst_id` NOT IN (SELECT `persinst`.`persinst_id` FROM `persinst`) LIMIT 1"); if ($result->num_rows === 0) { $result->close(); $result = null; return; } $result->close(); $result = null; $this->_mysqli_noda->do_update_query_large("DELETE FROM `persinst_fulltext` WHERE NOT EXISTS (SELECT 1 FROM `persinst` WHERE `persinst`.`persinst_id` = `persinst_fulltext`.`persinst_id`)"); } /** * Gets the entries to update. * * @return array */ public function getNewEntries():array { $result = $this->_mysqli_noda->do_read_query("SELECT `persinst_id`, `persinst_anzeigename`, `persinst_name` FROM `persinst` WHERE NOT EXISTS (SELECT 1 FROM `persinst_fulltext` WHERE `persinst`.`persinst_id` = `persinst_fulltext`.`persinst_id` AND `persinst`.`persinst_erfasst_am` <= `persinst_fulltext`.`update_timestamp`) LIMIT 10000"); if ($result->num_rows === 0) { $result->close(); $result = null; return []; } $toUpdate = []; while ($cur = $result->fetch_assoc()) { $persinst_id = (int)$cur['persinst_id']; unset($cur['persinst_id']); $toUpdate[$persinst_id] = $cur; } $result->close(); $result = null; $tlResult = $this->_mysqli_noda->do_read_query("SELECT `persinst_translation`.`persinst_id`, `trans_name` AS `name` FROM `persinst_translation` WHERE `persinst_translation`.`persinst_id` IN (" . implode(', ', array_keys($toUpdate)) . ")"); $translations = []; while ($cur = $tlResult->fetch_assoc()) { $persinst_id = (int)$cur['persinst_id']; if (empty($translations[$persinst_id])) { $translations[$persinst_id] = [$cur['name']]; } else $translations[$persinst_id][] = $cur['name']; } $tlResult->close(); $tlResult = null; $newEntries = []; foreach ($toUpdate as $persinst_id => $values) { if (isset($translations[$persinst_id])) $values = array_merge($values, $translations[$persinst_id]); $newEntries[$persinst_id] = implode(' ', array_unique($values)); } return $newEntries; } /** * Loads the list of entries to update. * * @return void */ public function update():void { if (empty($toUpdate = $this->getNewEntries())) { return; } if (count($toUpdate) > 1) { $this->_mysqli_noda->autocommit(false); } $updateStmt = $this->_mysqli_noda->do_prepare("INSERT INTO `persinst_fulltext` (`persinst_id`, `content`, `update_timestamp`) VALUES (?, ?, NOW()) ON DUPLICATE KEY UPDATE `content` = ?, `update_timestamp` = NOW()"); foreach ($toUpdate as $key => $value) { $updateStmt->bind_param("iss", $key, $value, $value); $updateStmt->execute(); } $updateStmt->close(); $updateStmt = null; if (count($toUpdate) > 1) { $this->_mysqli_noda->commit(); $this->_mysqli_noda->autocommit(true); } } /** * Sync: Wrapper function glueing together the sync process. * * @return void */ public function sync():void { $this->removeObsolete(); $this->update(); } /** * Constructor. * * @param MDMysqli $mysqli_noda DB connection. * * @return void */ public function __construct(MDMysqli $mysqli_noda) { $this->_mysqli_noda = $mysqli_noda; } }