Version1015Date20211104103506.php 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\Files_External\Migration;
  8. use Closure;
  9. use OC\Files\Cache\Storage;
  10. use OCP\DB\Exception;
  11. use OCP\DB\IResult;
  12. use OCP\DB\ISchemaWrapper;
  13. use OCP\IDBConnection;
  14. use OCP\Migration\IOutput;
  15. use OCP\Migration\SimpleMigrationStep;
  16. use Psr\Log\LoggerInterface;
  17. class Version1015Date20211104103506 extends SimpleMigrationStep {
  18. /** @var IDBConnection */
  19. private $connection;
  20. /** @var LoggerInterface */
  21. private $logger;
  22. public function __construct(IDBConnection $connection, LoggerInterface $logger) {
  23. $this->connection = $connection;
  24. $this->logger = $logger;
  25. }
  26. public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
  27. $qb = $this->connection->getQueryBuilder();
  28. $qb->update('storages')
  29. ->set('id', $qb->createParameter('newId'))
  30. ->where($qb->expr()->eq('id', $qb->createParameter('oldId')));
  31. $mounts = $this->getS3Mounts();
  32. if (!$mounts instanceof IResult) {
  33. throw new \Exception('Could not fetch existing mounts for migration');
  34. }
  35. while ($mount = $mounts->fetch()) {
  36. $config = $this->getStorageConfig((int)$mount['mount_id']);
  37. $hostname = $config['hostname'];
  38. $bucket = $config['bucket'];
  39. $key = $config['key'];
  40. $oldId = Storage::adjustStorageId('amazon::' . $bucket);
  41. $newId = Storage::adjustStorageId('amazon::external::' . md5($hostname . ':' . $bucket . ':' . $key));
  42. try {
  43. $qb->setParameter('oldId', $oldId);
  44. $qb->setParameter('newId', $newId);
  45. $qb->execute();
  46. $this->logger->info('Migrated s3 storage id for mount with id ' . $mount['mount_id'] . ' to ' . $newId);
  47. } catch (Exception $e) {
  48. $this->logger->error('Failed to migrate external s3 storage id for mount with id ' . $mount['mount_id'], [
  49. 'exception' => $e
  50. ]);
  51. }
  52. }
  53. return null;
  54. }
  55. /**
  56. * @throws Exception
  57. * @return \OCP\DB\IResult|int
  58. */
  59. private function getS3Mounts() {
  60. $qb = $this->connection->getQueryBuilder();
  61. $qb->select('m.mount_id')
  62. ->selectAlias('c.value', 'bucket')
  63. ->from('external_mounts', 'm')
  64. ->innerJoin('m', 'external_config', 'c', 'c.mount_id = m.mount_id')
  65. ->where($qb->expr()->eq('m.storage_backend', $qb->createPositionalParameter('amazons3')))
  66. ->andWhere($qb->expr()->eq('c.key', $qb->createPositionalParameter('bucket')));
  67. return $qb->execute();
  68. }
  69. /**
  70. * @throws Exception
  71. */
  72. private function getStorageConfig(int $mountId): array {
  73. $qb = $this->connection->getQueryBuilder();
  74. $qb->select('key', 'value')
  75. ->from('external_config')
  76. ->where($qb->expr()->eq('mount_id', $qb->createPositionalParameter($mountId)));
  77. $config = [];
  78. foreach ($qb->execute()->fetchAll() as $row) {
  79. $config[$row['key']] = $row['value'];
  80. }
  81. return $config;
  82. }
  83. }