mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
In older versions of Appwrite, the internal ID was the $internalId attribute. However, it has now changed to $sequence so that it can align with the publicly exposed attribute for an auto-incrementing ID. The problem with this change is that data in the cache still references the old $internalId attribute, which can lead to inconsistencies and errors when accessing cached documents. To resolve this issue, we need to clear the cache for all collections and documents at the beginning of the migration so that the new $sequence attribute is used.
141 lines
4.1 KiB
PHP
141 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Appwrite\Migration\Version;
|
|
|
|
use Appwrite\Migration\Migration;
|
|
use Exception;
|
|
use Throwable;
|
|
use Utopia\CLI\Console;
|
|
use Utopia\Database\Database;
|
|
use Utopia\Database\Document;
|
|
use Utopia\Database\Exception\Conflict;
|
|
use Utopia\Database\Exception\Structure;
|
|
use Utopia\Database\Exception\Timeout;
|
|
|
|
class V23 extends Migration
|
|
{
|
|
/**
|
|
* @throws Throwable
|
|
*/
|
|
public function execute(): void
|
|
{
|
|
/**
|
|
* Disable SubQueries for Performance.
|
|
*/
|
|
$subQueries = [
|
|
'subQueryAttributes',
|
|
'subQueryAuthenticators',
|
|
'subQueryChallenges',
|
|
'subQueryDevKeys',
|
|
'subQueryIndexes',
|
|
'subQueryKeys',
|
|
'subQueryMemberships',
|
|
'subQueryPlatforms',
|
|
'subQueryProjectVariables',
|
|
'subQuerySessions',
|
|
'subQueryTargets',
|
|
'subQueryTokens',
|
|
'subQueryTopicTargets',
|
|
'subQueryVariables',
|
|
'subQueryWebhooks',
|
|
];
|
|
foreach ($subQueries as $name) {
|
|
Database::addFilter(
|
|
$name,
|
|
fn () => null,
|
|
fn () => []
|
|
);
|
|
}
|
|
|
|
Console::info('Migrating collections');
|
|
$this->migrateCollections();
|
|
|
|
Console::info('Migrating documents');
|
|
$this->forEachDocument($this->migrateDocument(...));
|
|
}
|
|
|
|
/**
|
|
* Migrate Collections.
|
|
*
|
|
* @return void
|
|
* @throws Exception|Throwable
|
|
*/
|
|
private function migrateCollections(): void
|
|
{
|
|
$projectInternalId = $this->project->getSequence();
|
|
|
|
if (empty($projectInternalId)) {
|
|
throw new Exception('Project ID is null');
|
|
}
|
|
|
|
$collectionType = match ($projectInternalId) {
|
|
'console' => 'console',
|
|
default => 'projects',
|
|
};
|
|
|
|
$collections = $this->collections[$collectionType];
|
|
|
|
foreach ($collections as $collection) {
|
|
$id = $collection['$id'];
|
|
|
|
if (empty($id)) {
|
|
continue;
|
|
}
|
|
|
|
Console::log("Migrating collection \"{$id}\"");
|
|
|
|
// Clear cache to ensure new $sequence is used
|
|
$this->dbForProject->purgeCachedCollection($id);
|
|
$this->dbForProject->purgeCachedDocument(Database::METADATA, $id);
|
|
|
|
switch ($id) {
|
|
case 'databases':
|
|
$attributes = [
|
|
'type',
|
|
];
|
|
try {
|
|
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
|
} catch (\Throwable $th) {
|
|
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
|
}
|
|
$this->dbForProject->purgeCachedCollection($id);
|
|
break;
|
|
case 'schedules':
|
|
try {
|
|
$this->dbForProject->updateAttribute($id, 'resourceInternalId', required: false);
|
|
} catch (Throwable $th) {
|
|
Console::warning("'resourceInternalId' from {$id}: {$th->getMessage()}");
|
|
}
|
|
$this->dbForProject->purgeCachedCollection($id);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fix run on each document
|
|
*
|
|
* @param Document $document
|
|
* @return Document
|
|
* @throws Conflict
|
|
* @throws Structure
|
|
* @throws Timeout
|
|
* @throws \Utopia\Database\Exception
|
|
* @throws \Utopia\Database\Exception\Authorization
|
|
* @throws \Utopia\Database\Exception\Query
|
|
*/
|
|
private function migrateDocument(Document $document): Document
|
|
{
|
|
switch ($document->getCollection()) {
|
|
case 'databases':
|
|
$document->getAttribute('type', $document->getAttribute('type', 'tablesdb'));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return $document;
|
|
}
|
|
}
|