1
0
Fork 0
mirror of synced 2024-10-02 02:07:04 +13:00

feat: migration for 0.15 collections

This commit is contained in:
Torsten Dittmann 2022-06-21 12:17:18 +02:00
parent db35fc92d5
commit 87f79509a0
2 changed files with 372 additions and 1 deletions

View file

@ -45,7 +45,7 @@ abstract class Migration
'0.14.0' => 'V13',
'0.14.1' => 'V13',
'0.14.2' => 'V13',
'0.15.0' => 'V13'
'0.15.0' => 'V14'
];
/**
@ -228,6 +228,87 @@ abstract class Migration
}
}
/**
* Creates attribute from collections.php
*
* @param \Utopia\Database\Database $database
* @param string $collectionId
* @param string $attributeId
* @return void
* @throws \Exception
* @throws \Utopia\Database\Exception\Duplicate
* @throws \Utopia\Database\Exception\Limit
*/
public function createAttributeFromCollection(Database $database, string $collectionId, string $attributeId): void
{
$collection = Config::getParam('collections', [])[$collectionId] ?? null;
if (is_null($collection)) {
throw new Exception("Collection {$collectionId} not found");
}
$attributes = $collection['attributes'];
$attributeKey = array_search($attributeId, array_column($attributes, '$id'));
if (!$attributeKey) {
throw new Exception("Attribute {$attributeId} not found");
}
$attribute = $attributes[$attributeKey];
$database->createAttribute(
collection: $collectionId,
id: $attributeId,
type: $attribute['type'],
size: $attribute['size'],
required: $attribute['required'] ?? false,
default: $attribute['default'] ?? null,
signed: $attribute['signed'] ?? false,
array: $attribute['array'] ?? false,
format: $attribute['format'] ?? '',
formatOptions: $attribute['formatOptions'] ?? [],
filters: $attribute['filters'] ?? [],
);
}
/**
* Creates index from collections.php
*
* @param \Utopia\Database\Database $database
* @param string $collectionId
* @param string $indexId
* @return void
* @throws \Exception
* @throws \Utopia\Database\Exception\Duplicate
* @throws \Utopia\Database\Exception\Limit
*/
public function createIndexFromCollection(Database $database, string $collectionId, string $indexId): void
{
$collection = Config::getParam('collections', [])[$collectionId] ?? null;
if (is_null($collection)) {
throw new Exception("Collection {$collectionId} not found");
}
$indexes = $collection['indexes'];
$indexKey = array_search($indexId, array_column($indexes, '$id'));
if (!$indexKey) {
throw new Exception("Attribute {$indexId} not found");
}
$index = $indexes[$indexKey];
$database->createIndex(
collection: $collectionId,
id: $indexId,
type: $index['type'],
attributes: $index['attributes'],
lengths: $index['lengths'] ?? [],
orders: $index['orders'] ?? []
);
}
/**
* Executes migration for set project.
*/

View file

@ -0,0 +1,290 @@
<?php
namespace Appwrite\Migration\Version;
use Appwrite\Migration\Migration;
use Utopia\CLI\Console;
use Utopia\Database\Document;
class V14 extends Migration
{
public function execute(): void
{
Console::log('Migrating project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
Console::info('Migrating Collections');
$this->migrateCollections();
Console::info('Migrating Documents');
$this->forEachDocument([$this, 'fixDocument']);
}
/**
* Migrate all Collections.
*
* @return void
*/
protected function migrateCollections(): void
{
foreach ($this->collections as $collection) {
$id = $collection['$id'];
Console::log("- {$id}");
switch ($id) {
case 'attributes':
case 'indexes':
try {
/**
* Create 'collectionInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'collectionInternalId');
} catch (\Throwable $th) {
Console::warning("'collectionInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_collection' index
*/
$this->projectDB->deleteIndex($id, '_key_collection');
$this->createIndexFromCollection($this->projectDB, $id, '_key_collection');
} catch (\Throwable $th) {
Console::warning("'_key_collection' from {$id}: {$th->getMessage()}");
}
break;
case 'projects':
try {
/**
* Create 'teamInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'teamInternalId');
} catch (\Throwable $th) {
Console::warning("'collectionInternalId' from {$id}: {$th->getMessage()}");
}
break;
case 'platforms':
try {
/**
* Create 'projectInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'projectInternalId');
} catch (\Throwable $th) {
Console::warning("'collectionInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_project' index
*/
$this->projectDB->deleteIndex($id, '_key_project');
$this->createIndexFromCollection($this->projectDB, $id, '_key_project');
} catch (\Throwable $th) {
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
}
break;
case 'domains':
try {
/**
* Create 'projectInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'projectInternalId');
} catch (\Throwable $th) {
Console::warning("'projectInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_project' index
*/
$this->projectDB->deleteIndex($id, '_key_project');
$this->createIndexFromCollection($this->projectDB, $id, '_key_project');
} catch (\Throwable $th) {
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
}
break;
case 'keys':
try {
/**
* Create 'projectInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'projectInternalId');
} catch (\Throwable $th) {
Console::warning("'projectInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Create 'expire' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'expire');
} catch (\Throwable $th) {
Console::warning("'expire' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_project' index
*/
$this->projectDB->deleteIndex($id, '_key_project');
$this->createIndexFromCollection($this->projectDB, $id, '_key_project');
} catch (\Throwable $th) {
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
}
break;
case 'webhooks':
try {
/**
* Create 'projectInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'projectInternalId');
} catch (\Throwable $th) {
Console::warning("'projectInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_project' index
*/
$this->projectDB->deleteIndex($id, '_key_project');
$this->createIndexFromCollection($this->projectDB, $id, '_key_project');
} catch (\Throwable $th) {
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
}
break;
case 'users':
try {
/**
* Create 'phone' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'phone');
} catch (\Throwable $th) {
Console::warning("'phone' from {$id}: {$th->getMessage()}");
}
try {
/**
* Create 'phoneVerification' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'phoneVerification');
} catch (\Throwable $th) {
Console::warning("'phoneVerification' from {$id}: {$th->getMessage()}");
}
try {
/**
* Create '_key_phone' index
*/
$this->createIndexFromCollection($this->projectDB, $id, '_key_phone');
} catch (\Throwable $th) {
Console::warning("'_key_project' from {$id}: {$th->getMessage()}");
}
break;
case 'tokens':
try {
/**
* Create 'userInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'userInternalId');
} catch (\Throwable $th) {
Console::warning("'userInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_user' index
*/
$this->projectDB->deleteIndex($id, '_key_user');
$this->createIndexFromCollection($this->projectDB, $id, '_key_user');
} catch (\Throwable $th) {
Console::warning("'_key_user' from {$id}: {$th->getMessage()}");
}
break;
case 'sessions':
try {
/**
* Create 'userInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'userInternalId');
} catch (\Throwable $th) {
Console::warning("'userInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_user' index
*/
$this->projectDB->deleteIndex($id, '_key_user');
$this->createIndexFromCollection($this->projectDB, $id, '_key_user');
} catch (\Throwable $th) {
Console::warning("'_key_user' from {$id}: {$th->getMessage()}");
}
break;
case 'memberships':
try {
/**
* Create 'teamInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'teamInternalId');
} catch (\Throwable $th) {
Console::warning("'userInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Create 'userInternalId' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'userInternalId');
} catch (\Throwable $th) {
Console::warning("'userInternalId' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_unique' index
*/
$this->projectDB->deleteIndex($id, '_key_unique');
$this->createIndexFromCollection($this->projectDB, $id, '_key_unique');
} catch (\Throwable $th) {
Console::warning("'_key_unique' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_team' index
*/
$this->projectDB->deleteIndex($id, '_key_team');
$this->createIndexFromCollection($this->projectDB, $id, '_key_team');
} catch (\Throwable $th) {
Console::warning("'_key_team' from {$id}: {$th->getMessage()}");
}
try {
/**
* Re-Create '_key_user' index
*/
$this->projectDB->deleteIndex($id, '_key_user');
$this->createIndexFromCollection($this->projectDB, $id, '_key_user');
} catch (\Throwable $th) {
Console::warning("'_key_user' from {$id}: {$th->getMessage()}");
}
break;
}
usleep(100000);
}
}
/**
* Fix run on each document
*
* @param \Utopia\Database\Document $document
* @return \Utopia\Database\Document
*/
protected function fixDocument(Document $document)
{
switch ($document->getCollection()) {
case 'projects':
/**
* Bump Project version number.
*/
$document->setAttribute('version', '0.15.0');
break;
}
return $document;
}
}