Skip to content

Commit

Permalink
fix(migration): Fix migration for MySQL which does not allow joining …
Browse files Browse the repository at this point in the history
…a written table as a select

Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Aug 13, 2024
1 parent aeea1f5 commit 31f294d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 5 deletions.
3 changes: 1 addition & 2 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<name>Photos</name>
<summary>Your memories under your control</summary>
<description>Your memories under your control</description>
<version>3.0.1</version>
<version>3.0.2</version>
<licence>agpl</licence>
<author mail="[email protected]">John Molakvoæ</author>
<namespace>Photos</namespace>
Expand All @@ -22,7 +22,6 @@
<website>https://github.com/nextcloud/photos</website>
<bugs>https://github.com/nextcloud/photos/issues</bugs>
<repository>https://github.com/nextcloud/photos.git</repository>
<default_enable />
<dependencies>
<nextcloud min-version="30" max-version="30" />
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@

use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

/**
* Migrate the photosSourceFolder user config to photosSourceFolders
*/
class Version30000Date20240417075404 extends SimpleMigrationStep {
class Version30000Date20240417075405 extends SimpleMigrationStep {
public function __construct(
private IDBConnection $db,
) {
Expand All @@ -36,13 +37,26 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array
->where($select->expr()->eq('appid', $select->expr()->literal('photos')))
->andWhere($select->expr()->eq('configkey', $select->expr()->literal('photosSourceFolders')));

$result = $select->executeQuery();
$alreadyMigrated = array_map(static fn (array $row) => $row['userid'], $result->fetchAll());
$result->closeCursor();

// Remove old entries for users who already have the new one
$delete = $this->db->getQueryBuilder();
$delete->delete('preferences')
->where($delete->expr()->eq('appid', $delete->expr()->literal('photos')))
->andWhere($delete->expr()->eq('configkey', $delete->expr()->literal('photosSourceFolder')))
->andWhere($delete->expr()->in('userid', $delete->createFunction($select->getSQL())))
->executeStatement();
->andWhere($delete->expr()->in(
'userid',
$delete->createParameter('chunk'),
IQueryBuilder::PARAM_STR
));

$chunks = array_chunk($alreadyMigrated, 1000);
foreach ($chunks as $chunk) {
$delete->setParameter('chunk', $chunk, IQueryBuilder::PARAM_STR_ARRAY);
$delete->executeStatement();
}

// Update remaining old entries to new ones
$update = $this->db->getQueryBuilder();
Expand Down
102 changes: 102 additions & 0 deletions tests/Migration/Version30000Date20240417075405Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/


namespace OCA\Photos\Tests\Migration;

use OCA\Photos\Migration\Version30000Date20240417075405;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use Test\TestCase;

/**
* @group DB
*/
class Version30000Date20240417075405Test extends TestCase {
protected IDBConnection $connection;

protected function setUp(): void {
parent::setUp();

$this->connection = \OCP\Server::get(IDBConnection::class);
}

protected function tearDown(): void {
$this->deleteTestEntries();
parent::tearDown();
}

protected function deleteTestEntries(): void {
$delete = $this->connection->getQueryBuilder();
$delete->delete('preferences')
->where($delete->expr()->like('userid', $delete->createNamedParameter('Version30000Date20240417075405Test%')));
$delete->executeStatement();
}

protected function createTestEntries(): void {
$this->deleteTestEntries();

$insert = $this->connection->getQueryBuilder();
$insert->insert('preferences')
->values([
'userid' => $insert->createParameter('userid'),
'appid' => $insert->createNamedParameter('photos'),
'configkey' => $insert->createParameter('configkey'),
'configvalue' => $insert->createNamedParameter('value'),
]);

$this->connection->beginTransaction();
for ($i = 1; $i <= 3000; $i++) {
$mod = $i % 3;
if ($mod !== 0) {
$insert->setParameter('userid', 'Version30000Date20240417075405Test#' . $i)
->setParameter('configkey', 'photosSourceFolder');
$insert->executeStatement();
}
if ($mod !== 1) {
$insert->setParameter('userid', 'Version30000Date20240417075405Test#' . $i)
->setParameter('configkey', 'photosSourceFolders');
$insert->executeStatement();
}
}
$this->connection->commit();
}

public function testPostSchemaChange(): void {
$migration = new Version30000Date20240417075405($this->connection);

$this->createTestEntries();


$migration->postSchemaChange(
$this->createMock(IOutput::class),
\Closure::fromCallable(fn () => false),
[]
);

$select = $this->connection->getQueryBuilder();
$select->select($select->func()->count())
->from('preferences')
->where($select->expr()->like('userid', $select->createNamedParameter('Version30000Date20240417075405Test%')))
->andWhere($select->expr()->eq('appid', $select->expr()->literal('photos')))
->andWhere($select->expr()->eq('configkey', $select->expr()->literal('photosSourceFolder')));
$result = $select->executeQuery();
$this->assertEquals(0, $result->fetchOne());
$result->closeCursor();

$select = $this->connection->getQueryBuilder();
$select->select($select->func()->count())
->from('preferences')
->where($select->expr()->like('userid', $select->createNamedParameter('Version30000Date20240417075405Test%')))
->andWhere($select->expr()->eq('appid', $select->expr()->literal('photos')))
->andWhere($select->expr()->eq('configkey', $select->expr()->literal('photosSourceFolders')));
$result = $select->executeQuery();
$this->assertEquals(3000, $result->fetchOne());
$result->closeCursor();
}
}

0 comments on commit 31f294d

Please sign in to comment.