163 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?PHP
 | |
| /**
 | |
|  * Contains a class for keeping the persinst fulltext index in sync.
 | |
|  *
 | |
|  * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 | |
|  */
 | |
| 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<string>
 | |
|      */
 | |
|     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;
 | |
| 
 | |
|     }
 | |
| }
 |