Fix order:random not working on SQlite

This commit is contained in:
Marcos Del Sol Vives 2024-02-16 18:21:45 +01:00 committed by Shish
parent 5c4b7c1284
commit b3eb5e7b03
2 changed files with 21 additions and 4 deletions

View file

@ -439,4 +439,19 @@ class Database
$this->execute("ALTER TABLE $table RENAME COLUMN {$column}_b TO $column");
}
}
/**
* Generates a deterministic pseudorandom order based on a seed and a column ID
*/
public function seeded_random(int $seed, string $id_column): string
{
$d = $this->get_driver_id();
if ($d == DatabaseDriverID::MYSQL) {
// MySQL supports RAND(n), where n is a random seed. Use that.
return "RAND($seed)";
}
// As fallback, use MD5 as a DRBG.
return "MD5(CONCAT($seed, CONCAT('+', $id_column)))";
}
}

View file

@ -155,6 +155,8 @@ class Index extends Extension
public function onSearchTermParse(SearchTermParseEvent $event): void
{
global $database;
if (is_null($event->term)) {
return;
}
@ -235,14 +237,14 @@ class Index extends Extension
} elseif (preg_match("/^order[=|:]random[_]([0-9]{1,4})$/i", $event->term, $matches)) {
// requires a seed to avoid duplicates
// since the tag can't be changed during the parseevent, we instead generate the seed during submit using js
$seed = $matches[1];
$event->order = "RAND($seed)";
$seed = (int)$matches[1];
$event->order = $database->seeded_random($seed, "images.id");
} elseif (preg_match("/^order[=|:]dailyshuffle$/i", $event->term, $matches)) {
// will use today's date as seed, thus allowing for a dynamic randomized list without outside intervention.
// This way the list will change every day, giving a more dynamic feel to the imageboard.
// recommended to change homepage to "post/list/order:dailyshuffle/1"
$seed = date("Ymd");
$event->order = "RAND($seed)";
$seed = (int)date("Ymd");
$event->order = $database->seeded_random($seed, "images.id");
}
// If we've reached this far, and nobody else has done anything with this term, then treat it as a tag