From 29446a29f58b484817e6c9798c736e5f531c21ee Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 14 Sep 2025 22:36:01 +0200 Subject: Recovery: skip broken entries during CLI export/import (#7949) * Recovery: skip broken entries during CLI export/import fix https://github.com/FreshRSS/FreshRSS/discussions/7927 ``` 25605/25605 (48 broken) ``` Help with *database malformed* or other corruption. * Compatibility multiple databases --- app/Models/EntryDAO.php | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'app/Models/EntryDAO.php') diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 4aa7c5056..cd7bcd2ff 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -27,6 +27,21 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo { return str_replace('INSERT INTO ', 'INSERT IGNORE INTO ', $sql); } + protected static function sqlLimitAll(): string { + // https://dev.mysql.com/doc/refman/9.4/en/select.html + return '18446744073709551615'; // Maximum unsigned BIGINT in MySQL, which neither supports ALL nor -1 + } + + public static function sqlLimit(int $limit = -1, int $offset = 0): string { + if ($limit < 0 && $offset <= 0) { + return ''; + } + if ($limit < 1) { + $limit = static::sqlLimitAll(); + } + return "LIMIT {$limit} OFFSET {$offset}"; + } + public static function sqlRandom(): string { return 'RAND()'; } @@ -739,18 +754,21 @@ SQL; } } - /** @return Traversable */ - public function selectAll(?int $limit = null): Traversable { + /** + * @param 'ASC'|'DESC' $order + * @return Traversable + */ + public function selectAll(string $order = 'ASC', int $limit = -1, int $offset = 0): Traversable { $content = static::isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content'; $hash = static::sqlHexEncode('hash'); + $order = in_array($order, ['ASC', 'DESC'], true) ? $order : 'ASC'; + $sqlLimit = static::sqlLimit($limit, $offset); $sql = <<= 0) { - $sql .= ' ORDER BY id DESC LIMIT ' . $limit; - } $stm = $this->pdo->query($sql); if ($stm !== false) { while (is_array($row = $stm->fetch(PDO::FETCH_ASSOC))) { @@ -762,7 +780,7 @@ SQL; $info = $this->pdo->errorInfo(); /** @var array{0:string,1:int,2:string} $info */ if ($this->autoUpdateDb($info)) { - yield from $this->selectAll(); + yield from $this->selectAll($order, $limit, $offset); } else { Minz_Log::error(__METHOD__ . ' error: ' . json_encode($info)); } -- cgit v1.2.3