Add classes for keeping the fulltext (search) tables in sync
This commit is contained in:
parent
041d3598eb
commit
c84e3401ff
162
src/NodaPersinstFulltextSync.php
Normal file
162
src/NodaPersinstFulltextSync.php
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
<?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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
163
src/NodaPlaceFulltextSync.php
Normal file
163
src/NodaPlaceFulltextSync.php
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
<?PHP
|
||||||
|
/**
|
||||||
|
* Contains a class for keeping the places fulltext index in sync.
|
||||||
|
*
|
||||||
|
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||||
|
*/
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for keeping the places fulltext index in sync.
|
||||||
|
*/
|
||||||
|
final class NodaPlaceFulltextSync {
|
||||||
|
|
||||||
|
/** @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 `orte_fulltext`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `orte`
|
||||||
|
WHERE `orte`.`ort_id` = `orte_fulltext`.`ort_id`)
|
||||||
|
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 `orte_fulltext`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `orte`
|
||||||
|
WHERE `orte`.`ort_id` = `orte_fulltext`.`ort_id`)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entries to update.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public function getNewEntries():array {
|
||||||
|
|
||||||
|
$result = $this->_mysqli_noda->do_read_query("SELECT `ort_id`,
|
||||||
|
`ort_name`
|
||||||
|
FROM `orte`
|
||||||
|
WHERE NOT EXISTS (SELECT 1
|
||||||
|
FROM `orte_fulltext`
|
||||||
|
WHERE `orte`.`ort_id` = `orte_fulltext`.`ort_id`
|
||||||
|
AND `orte`.`ort_erfasst_am` <= `orte_fulltext`.`update_timestamp`)
|
||||||
|
LIMIT 10000");
|
||||||
|
|
||||||
|
if ($result->num_rows === 0) {
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$toUpdate = [];
|
||||||
|
|
||||||
|
while ($cur = $result->fetch_assoc()) {
|
||||||
|
$ort_id = (int)$cur['ort_id'];
|
||||||
|
unset($cur['ort_id']);
|
||||||
|
$toUpdate[$ort_id] = $cur;
|
||||||
|
}
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
|
||||||
|
$tlResult = $this->_mysqli_noda->do_read_query("SELECT `ort_translation`.`ort_id`, `trans_name` AS `name`
|
||||||
|
FROM `ort_translation`
|
||||||
|
WHERE `ort_translation`.`ort_id` IN (" . implode(', ', array_keys($toUpdate)) . ")");
|
||||||
|
|
||||||
|
$translations = [];
|
||||||
|
while ($cur = $tlResult->fetch_assoc()) {
|
||||||
|
$ort_id = (int)$cur['ort_id'];
|
||||||
|
if (empty($translations[$ort_id])) {
|
||||||
|
$translations[$ort_id] = [$cur['name']];
|
||||||
|
}
|
||||||
|
else $translations[$ort_id][] = $cur['name'];
|
||||||
|
}
|
||||||
|
$tlResult->close();
|
||||||
|
$tlResult = null;
|
||||||
|
|
||||||
|
$newEntries = [];
|
||||||
|
|
||||||
|
foreach ($toUpdate as $ort_id => $values) {
|
||||||
|
if (isset($translations[$ort_id])) $values = array_merge($values, $translations[$ort_id]);
|
||||||
|
$newEntries[$ort_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 `orte_fulltext`
|
||||||
|
(`ort_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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
167
src/NodaSourceFulltextSync.php
Normal file
167
src/NodaSourceFulltextSync.php
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
<?PHP
|
||||||
|
/**
|
||||||
|
* Contains a class for keeping the source fulltext index in sync.
|
||||||
|
*
|
||||||
|
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||||
|
*/
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for keeping the source fulltext index in sync.
|
||||||
|
*/
|
||||||
|
final class NodaSourceFulltextSync {
|
||||||
|
|
||||||
|
/** @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 `source_fulltext_search`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `source`
|
||||||
|
WHERE `source`.`source_id` = `source_fulltext_search`.`source_id`)
|
||||||
|
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 `source_fulltext_search`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `source`
|
||||||
|
WHERE `source`.`source_id` = `source_fulltext_search`.`source_id`)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entries to update.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public function getNewEntries():array {
|
||||||
|
|
||||||
|
$result = $this->_mysqli_noda->do_read_query("SELECT `source_id`,
|
||||||
|
`source_title`, `source_year`, `source_booktitle`, `source_venue`,
|
||||||
|
`source_volume`, `source_issue`, `source_pages`, `source_url`,
|
||||||
|
`source_doi`, `source_isbn`, `source_license`
|
||||||
|
FROM `source`
|
||||||
|
WHERE NOT EXISTS (SELECT 1
|
||||||
|
FROM `source_fulltext_search`
|
||||||
|
WHERE `source`.`source_id` = `source_fulltext_search`.`source_id`
|
||||||
|
AND `source`.`source_update_timestamp` <= `source_fulltext_search`.`update_timestamp`)");
|
||||||
|
|
||||||
|
if ($result->num_rows === 0) {
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$toUpdate = [];
|
||||||
|
|
||||||
|
while ($cur = $result->fetch_assoc()) {
|
||||||
|
$cur['authors'] = "";
|
||||||
|
$source_id = (int)$cur['source_id'];
|
||||||
|
unset($cur['source_id']);
|
||||||
|
$toUpdate[$source_id] = $cur;
|
||||||
|
}
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
|
||||||
|
$authorsResult = $this->_mysqli_noda->do_read_query("SELECT `source_author`.`source_id`, `persinst_anzeigename` AS `name`
|
||||||
|
FROM `persinst`, `source_author`
|
||||||
|
WHERE `source_author`.`author_id` = `persinst`.`persinst_id`
|
||||||
|
AND `source_author`.`source_id` IN (" . implode(', ', array_keys($toUpdate)) . ")");
|
||||||
|
|
||||||
|
$authors = [];
|
||||||
|
while ($cur = $authorsResult->fetch_assoc()) {
|
||||||
|
$source_id = (int)$cur['source_id'];
|
||||||
|
if (empty($authors[$source_id])) {
|
||||||
|
$authors[$source_id] = [$cur['name']];
|
||||||
|
}
|
||||||
|
else $authors[$source_id][] = $cur['name'];
|
||||||
|
}
|
||||||
|
$authorsResult->close();
|
||||||
|
$authorsResult = null;
|
||||||
|
|
||||||
|
$newEntries = [];
|
||||||
|
|
||||||
|
foreach ($toUpdate as $source_id => $values) {
|
||||||
|
$cur = implode(' ', $values);
|
||||||
|
if (!empty($authors[$source_id])) $cur .= ' ' . implode(' ', array_unique($authors[$source_id]));
|
||||||
|
$newEntries[$source_id] = $cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 `source_fulltext_search`
|
||||||
|
(`source_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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
163
src/NodaTagFulltextSync.php
Normal file
163
src/NodaTagFulltextSync.php
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
<?PHP
|
||||||
|
/**
|
||||||
|
* Contains a class for keeping the tags fulltext index in sync.
|
||||||
|
*
|
||||||
|
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||||
|
*/
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for keeping the tags fulltext index in sync.
|
||||||
|
*/
|
||||||
|
final class NodaTagFulltextSync {
|
||||||
|
|
||||||
|
/** @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 `tag_fulltext`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `tag`
|
||||||
|
WHERE `tag`.`tag_id` = `tag_fulltext`.`tag_id`)
|
||||||
|
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 `tag_fulltext`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `tag`
|
||||||
|
WHERE `tag`.`tag_id` = `tag_fulltext`.`tag_id`)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entries to update.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public function getNewEntries():array {
|
||||||
|
|
||||||
|
$result = $this->_mysqli_noda->do_read_query("SELECT `tag_id`,
|
||||||
|
`tag_name`
|
||||||
|
FROM `tag`
|
||||||
|
WHERE NOT EXISTS (SELECT 1
|
||||||
|
FROM `tag_fulltext`
|
||||||
|
WHERE `tag`.`tag_id` = `tag_fulltext`.`tag_id`
|
||||||
|
AND `tag`.`tag_erfasst_am` <= `tag_fulltext`.`update_timestamp`)
|
||||||
|
LIMIT 10000");
|
||||||
|
|
||||||
|
if ($result->num_rows === 0) {
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$toUpdate = [];
|
||||||
|
|
||||||
|
while ($cur = $result->fetch_assoc()) {
|
||||||
|
$tag_id = (int)$cur['tag_id'];
|
||||||
|
unset($cur['tag_id']);
|
||||||
|
$toUpdate[$tag_id] = $cur;
|
||||||
|
}
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
|
||||||
|
$tlResult = $this->_mysqli_noda->do_read_query("SELECT `tag_translation`.`tag_id`, `trans_name` AS `name`
|
||||||
|
FROM `tag_translation`
|
||||||
|
WHERE `tag_translation`.`tag_id` IN (" . implode(', ', array_keys($toUpdate)) . ")");
|
||||||
|
|
||||||
|
$translations = [];
|
||||||
|
while ($cur = $tlResult->fetch_assoc()) {
|
||||||
|
$tag_id = (int)$cur['tag_id'];
|
||||||
|
if (empty($translations[$tag_id])) {
|
||||||
|
$translations[$tag_id] = [$cur['name']];
|
||||||
|
}
|
||||||
|
else $translations[$tag_id][] = $cur['name'];
|
||||||
|
}
|
||||||
|
$tlResult->close();
|
||||||
|
$tlResult = null;
|
||||||
|
|
||||||
|
$newEntries = [];
|
||||||
|
|
||||||
|
foreach ($toUpdate as $tag_id => $values) {
|
||||||
|
if (isset($translations[$tag_id])) $values = array_merge($values, $translations[$tag_id]);
|
||||||
|
$newEntries[$tag_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 `tag_fulltext`
|
||||||
|
(`tag_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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
163
src/NodaTimeFulltextSync.php
Normal file
163
src/NodaTimeFulltextSync.php
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
<?PHP
|
||||||
|
/**
|
||||||
|
* Contains a class for keeping the times fulltext index in sync.
|
||||||
|
*
|
||||||
|
* @author Joshua Ramon Enslin <joshua@museum-digital.de>
|
||||||
|
*/
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for keeping the times fulltext index in sync.
|
||||||
|
*/
|
||||||
|
final class NodaTimeFulltextSync {
|
||||||
|
|
||||||
|
/** @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 `zeiten_fulltext`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `zeiten`
|
||||||
|
WHERE `zeiten`.`zeit_id` = `zeiten_fulltext`.`zeit_id`)
|
||||||
|
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 `zeiten_fulltext`
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM `zeiten`
|
||||||
|
WHERE `zeiten`.`zeit_id` = `zeiten_fulltext`.`zeit_id`)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entries to update.
|
||||||
|
*
|
||||||
|
* @return array<string>
|
||||||
|
*/
|
||||||
|
public function getNewEntries():array {
|
||||||
|
|
||||||
|
$result = $this->_mysqli_noda->do_read_query("SELECT `zeit_id`,
|
||||||
|
`zeit_name`
|
||||||
|
FROM `zeiten`
|
||||||
|
WHERE NOT EXISTS (SELECT 1
|
||||||
|
FROM `zeiten_fulltext`
|
||||||
|
WHERE `zeiten`.`zeit_id` = `zeiten_fulltext`.`zeit_id`
|
||||||
|
AND `zeiten`.`zeit_erfasst_am` <= `zeiten_fulltext`.`update_timestamp`)
|
||||||
|
LIMIT 10000");
|
||||||
|
|
||||||
|
if ($result->num_rows === 0) {
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$toUpdate = [];
|
||||||
|
|
||||||
|
while ($cur = $result->fetch_assoc()) {
|
||||||
|
$zeit_id = (int)$cur['zeit_id'];
|
||||||
|
unset($cur['zeit_id']);
|
||||||
|
$toUpdate[$zeit_id] = $cur;
|
||||||
|
}
|
||||||
|
$result->close();
|
||||||
|
$result = null;
|
||||||
|
|
||||||
|
$tlResult = $this->_mysqli_noda->do_read_query("SELECT `zeit_translation`.`zeit_id`, `trans_name` AS `name`
|
||||||
|
FROM `zeit_translation`
|
||||||
|
WHERE `zeit_translation`.`zeit_id` IN (" . implode(', ', array_keys($toUpdate)) . ")");
|
||||||
|
|
||||||
|
$translations = [];
|
||||||
|
while ($cur = $tlResult->fetch_assoc()) {
|
||||||
|
$time_id = (int)$cur['zeit_id'];
|
||||||
|
if (empty($translations[$time_id])) {
|
||||||
|
$translations[$time_id] = [$cur['name']];
|
||||||
|
}
|
||||||
|
else $translations[$time_id][] = $cur['name'];
|
||||||
|
}
|
||||||
|
$tlResult->close();
|
||||||
|
$tlResult = null;
|
||||||
|
|
||||||
|
$newEntries = [];
|
||||||
|
|
||||||
|
foreach ($toUpdate as $zeit_id => $values) {
|
||||||
|
if (isset($translations[$zeit_id])) $values = array_merge($values, $translations[$zeit_id]);
|
||||||
|
$newEntries[$zeit_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 `zeiten_fulltext`
|
||||||
|
(`zeit_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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user