From 5f3d62600e80ff7e256deff904471cf8686edc37 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 6 Nov 2020 10:26:41 +0100 Subject: [PATCH] Fix repair mimetype step to not leave stray cursors Signed-off-by: Joas Schilling --- lib/private/Repair.php | 2 +- lib/private/Repair/RepairMimeTypes.php | 94 +++++++++++------------- tests/lib/Repair/RepairMimeTypesTest.php | 2 +- 3 files changed, 44 insertions(+), 54 deletions(-) diff --git a/lib/private/Repair.php b/lib/private/Repair.php index bba797a098..61857285f3 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -144,7 +144,7 @@ class Repair implements IOutput { public static function getRepairSteps() { return [ new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), \OC::$server->getDatabaseConnection(), false), - new RepairMimeTypes(\OC::$server->getConfig()), + new RepairMimeTypes(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()), new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()), new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()), new MoveUpdaterStepFile(\OC::$server->getConfig()), diff --git a/lib/private/Repair/RepairMimeTypes.php b/lib/private/Repair/RepairMimeTypes.php index 60a7df25f6..c5157f8161 100644 --- a/lib/private/Repair/RepairMimeTypes.php +++ b/lib/private/Repair/RepairMimeTypes.php @@ -33,84 +33,74 @@ namespace OC\Repair; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IConfig; +use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; class RepairMimeTypes implements IRepairStep { - /** - * @var \OCP\IConfig - */ + /** @var IConfig */ protected $config; + /** @var IDBConnection */ + protected $connection; - /** - * @var int - */ + /** @var int */ protected $folderMimeTypeId; - /** - * @param \OCP\IConfig $config - */ - public function __construct($config) { + public function __construct(IConfig $config, + IDBConnection $connection) { $this->config = $config; + $this->connection = $connection; } public function getName() { return 'Repair mime types'; } - private static function existsStmt() { - return \OC_DB::prepare(' - SELECT count(`mimetype`) - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - '); - } - - private static function getIdStmt() { - return \OC_DB::prepare(' - SELECT `id` - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - '); - } - - private static function insertStmt() { - return \OC_DB::prepare(' - INSERT INTO `*PREFIX*mimetypes` ( `mimetype` ) - VALUES ( ? ) - '); - } - - private static function updateByNameStmt() { - return \OC_DB::prepare(' - UPDATE `*PREFIX*filecache` - SET `mimetype` = ? - WHERE `mimetype` <> ? AND `mimetype` <> ? AND `name` ILIKE ? - '); - } - private function updateMimetypes($updatedMimetypes) { + $query = $this->connection->getQueryBuilder(); + $query->select('id') + ->from('mimetypes') + ->where($query->expr()->eq('mimetype', $query->createParameter('mimetype'), IQueryBuilder::PARAM_INT)); + $insert = $this->connection->getQueryBuilder(); + $insert->insert('mimetypes') + ->setValue('mimetype', $insert->createParameter('mimetype')); + if (empty($this->folderMimeTypeId)) { - $result = \OC_DB::executeAudited(self::getIdStmt(), ['httpd/unix-directory']); - $this->folderMimeTypeId = (int)$result->fetchOne(); + $query->setParameter('mimetype', 'httpd/unix-directory'); + $result = $query->execute(); + $this->folderMimeTypeId = (int)$result->fetchColumn(); + $result->closeCursor(); } + $update = $this->connection->getQueryBuilder(); + $update->update('filecache') + ->set('mimetype', $update->createParameter('mimetype')) + ->where($update->expr()->neq('mimetype', $update->createParameter('mimetype'), IQueryBuilder::PARAM_INT)) + ->andWhere($update->expr()->neq('mimetype', $update->createParameter('folder'), IQueryBuilder::PARAM_INT)) + ->andWhere($update->expr()->iLike('name', $update->createParameter('name'))) + ->setParameter('folder', $this->folderMimeTypeId); + $count = 0; foreach ($updatedMimetypes as $extension => $mimetype) { - $result = \OC_DB::executeAudited(self::existsStmt(), [$mimetype]); - $exists = $result->fetchOne(); + // get target mimetype id + $query->setParameter('mimetype', $mimetype); + $result = $query->execute(); + $mimetypeId = (int)$result->fetchColumn(); + $result->closeCursor(); - if (!$exists) { + if (!$mimetypeId) { // insert mimetype - \OC_DB::executeAudited(self::insertStmt(), [$mimetype]); + $insert->setParameter('mimetype', $mimetype); + $insert->execute(); + $mimetypeId = $insert->getLastInsertId(); } - // get target mimetype id - $result = \OC_DB::executeAudited(self::getIdStmt(), [$mimetype]); - $mimetypeId = $result->fetchOne(); - // change mimetype for files with x extension - $count += \OC_DB::executeAudited(self::updateByNameStmt(), [$mimetypeId, $this->folderMimeTypeId, $mimetypeId, '%.' . $extension]); + $update->setParameter('mimetype', $mimetypeId) + ->setParameter('name', '%' . $this->connection->escapeLikeParameter('.' . $extension)); + $count += $update->execute(); } return $count; diff --git a/tests/lib/Repair/RepairMimeTypesTest.php b/tests/lib/Repair/RepairMimeTypesTest.php index 6f0791964b..26a52459c2 100644 --- a/tests/lib/Repair/RepairMimeTypesTest.php +++ b/tests/lib/Repair/RepairMimeTypesTest.php @@ -50,7 +50,7 @@ class RepairMimeTypesTest extends \Test\TestCase { $this->storage = new \OC\Files\Storage\Temporary([]); - $this->repair = new \OC\Repair\RepairMimeTypes($config); + $this->repair = new \OC\Repair\RepairMimeTypes($config, \OC::$server->getDatabaseConnection()); } protected function tearDown(): void {