Version1141Date20220323143801.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\User_LDAP\Migration;
  8. use Closure;
  9. use OCP\DB\ISchemaWrapper;
  10. use OCP\DB\QueryBuilder\IQueryBuilder;
  11. use OCP\IDBConnection;
  12. use OCP\Migration\IOutput;
  13. use OCP\Migration\SimpleMigrationStep;
  14. class Version1141Date20220323143801 extends SimpleMigrationStep {
  15. public function __construct(
  16. private IDBConnection $dbc,
  17. ) {
  18. }
  19. /**
  20. * @param IOutput $output
  21. * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
  22. * @param array $options
  23. */
  24. public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
  25. foreach (['ldap_user_mapping', 'ldap_group_mapping'] as $tableName) {
  26. $qb = $this->dbc->getQueryBuilder();
  27. $qb->select('ldap_dn')
  28. ->from($tableName)
  29. ->where($qb->expr()->gt($qb->func()->octetLength('ldap_dn'), $qb->createNamedParameter('4000'), IQueryBuilder::PARAM_INT));
  30. $dnsTooLong = [];
  31. $result = $qb->executeQuery();
  32. while (($dn = $result->fetchOne()) !== false) {
  33. $dnsTooLong[] = $dn;
  34. }
  35. $result->closeCursor();
  36. $this->shortenDNs($dnsTooLong, $tableName);
  37. }
  38. }
  39. protected function shortenDNs(array $dns, string $table): void {
  40. $qb = $this->dbc->getQueryBuilder();
  41. $qb->update($table)
  42. ->set('ldap_dn', $qb->createParameter('shortenedDn'))
  43. ->where($qb->expr()->eq('ldap_dn', $qb->createParameter('originalDn')));
  44. $pageSize = 1000;
  45. $page = 0;
  46. do {
  47. $subset = array_slice($dns, $page * $pageSize, $pageSize);
  48. try {
  49. $this->dbc->beginTransaction();
  50. foreach ($subset as $dn) {
  51. $shortenedDN = mb_substr($dn, 0, 4000);
  52. $qb->setParameter('shortenedDn', $shortenedDN);
  53. $qb->setParameter('originalDn', $dn);
  54. $qb->executeStatement();
  55. }
  56. $this->dbc->commit();
  57. } catch (\Throwable $t) {
  58. $this->dbc->rollBack();
  59. throw $t;
  60. }
  61. $page++;
  62. } while (count($subset) === $pageSize);
  63. }
  64. /**
  65. * @param IOutput $output
  66. * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
  67. * @param array $options
  68. * @return null|ISchemaWrapper
  69. */
  70. public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
  71. /** @var ISchemaWrapper $schema */
  72. $schema = $schemaClosure();
  73. foreach (['ldap_user_mapping', 'ldap_group_mapping'] as $tableName) {
  74. $table = $schema->getTable($tableName);
  75. $column = $table->getColumn('ldap_dn');
  76. if ($column->getLength() > 4000) {
  77. $column->setLength(4000);
  78. }
  79. }
  80. return $schema;
  81. }
  82. }