1
0
Fork 0
mirror of synced 2024-06-01 10:29:48 +12:00

fix(migration): move iteration to parent class

This commit is contained in:
Torsten Dittmann 2021-01-14 13:05:49 +01:00
parent c51caac494
commit 328405a774
4 changed files with 183 additions and 160 deletions

View file

@ -4,38 +4,83 @@ namespace Appwrite\Migration;
use Appwrite\Database\Document;
use Appwrite\Database\Database;
use Utopia\CLI\Console;
use Utopia\Exception;
abstract class Migration
{
protected \PDO $db;
protected \PDO $db;
protected int $limit = 30;
protected int $sum = 30;
protected int $offset = 0;
protected Document $project;
protected Database $projectDB;
protected int $limit = 30;
protected int $sum = 30;
protected int $offset = 0;
protected Document $project;
protected Database $projectDB;
/**
* Migration constructor.
*/
public function __construct(\PDO $db)
{
$this->db = $db;
}
/**
* Migration constructor.
*/
public function __construct(\PDO $db)
{
$this->db = $db;
}
/**
* Set project for migration.
*/
public function setProject(Document $project, Database $projectDB): Migration
{
$this->project = $project;
$this->projectDB = $projectDB;
$this->projectDB->setNamespace('app_'.$project->getId());
return $this;
}
/**
* Set project for migration.
*/
public function setProject(Document $project, Database $projectDB): Migration
{
$this->project = $project;
$this->projectDB = $projectDB;
$this->projectDB->setNamespace('app_' . $project->getId());
return $this;
}
/**
* Executes migration for set project.
*/
abstract public function execute(): void;
/**
* Iterates through every document.
*
* @param function(Document): Document $callback
*/
public function forEachDocument(callable $callback)
{
while ($this->sum >= 30) {
$all = $this->projectDB->getCollection([
'limit' => $this->limit,
'offset' => $this->offset,
'orderType' => 'DESC',
]);
$this->sum = \count($all);
Console::log('Migrating: ' . $this->offset . ' / ' . $this->projectDB->getSum());
foreach ($all as $document) {
$document = call_user_func($callback, $document);
if (empty($document->getId())) {
throw new Exception('Missing ID');
}
try {
$new = $this->projectDB->overwriteDocument($document->getArrayCopy());
} catch (\Throwable $th) {
var_dump($document);
Console::error('Failed to update document: ' . $th->getMessage());
continue;
}
if ($new->getId() !== $document->getId()) {
throw new Exception('Duplication Error');
}
}
$this->offset = $this->offset + $this->limit;
}
}
/**
* Executes migration for set project.
*/
abstract public function execute(): void;
}

View file

@ -7,8 +7,8 @@ use Appwrite\Migration\Migration;
class V04 extends Migration
{
public function execute(): void
{
Console::log('I got nothing to do.');
}
public function execute(): void
{
Console::log('I got nothing to do.');
}
}

View file

@ -5,63 +5,25 @@ namespace Appwrite\Migration\Version;
use Appwrite\Migration\Migration;
use Utopia\Config\Config;
use Utopia\CLI\Console;
use Utopia\Exception;
use Appwrite\Database\Database;
use Appwrite\Database\Document;
class V05 extends Migration
{
public function execute(): void
{
$db = $this->db;
$project = $this->project;
$projectDB = $this->projectDB;
Console::log('Migrating project: ' . $project->getAttribute('name') . ' (' . $project->getId() . ')');
public function execute(): void
{
$db = $this->db;
$project = $this->project;
Console::log('Migrating project: ' . $project->getAttribute('name') . ' (' . $project->getId() . ')');
// Update all documents $uid -> $id
// Update all documents $uid -> $id
$limit = 30;
$sum = 30;
$offset = 0;
$this->forEachDocument([$this, 'fixDocument']);
while ($sum >= 30) {
$all = $projectDB->getCollection([
'limit' => $limit,
'offset' => $offset,
'orderType' => 'DESC',
]);
$sum = \count($all);
Console::log('Migrating: ' . $offset . ' / ' . $projectDB->getSum());
foreach ($all as $document) {
$document = $this->fixDocument($document);
if (empty($document->getId())) {
throw new Exception('Missing ID');
}
$schema = $_SERVER['_APP_DB_SCHEMA'] ?? '';
try {
$new = $projectDB->overwriteDocument($document->getArrayCopy());
} catch (\Throwable $th) {
var_dump($document);
Console::error('Failed to update document: ' . $th->getMessage());
continue;
}
if ($new->getId() !== $document->getId()) {
throw new Exception('Duplication Error');
}
}
$offset = $offset + $limit;
}
$schema = $_SERVER['_APP_DB_SCHEMA'] ?? '';
try {
$statement = $db->prepare("
$statement = $db->prepare("
CREATE TABLE IF NOT EXISTS `template.database.unique` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
@ -76,89 +38,89 @@ class V05 extends Migration
ALTER TABLE `{$schema}`.`app_{$project->getId()}.audit.audit` ADD INDEX IF NOT EXISTS `index_1` (`userId` ASC);
");
$statement->closeCursor();
$statement->closeCursor();
$statement->execute();
} catch (\Exception $e) {
Console::error('Failed to alter table for project: ' . $project->getId() . ' with message: ' . $e->getMessage() . '/');
}
}
private function fixDocument(Document $document)
{
$providers = Config::getParam('providers');
switch ($document->getAttribute('$collection')) {
case Database::SYSTEM_COLLECTION_PROJECTS:
foreach ($providers as $key => $provider) {
if (!empty($document->getAttribute('usersOauth' . \ucfirst($key) . 'Appid'))) {
$document
->setAttribute('usersOauth2' . \ucfirst($key) . 'Appid', $document->getAttribute('usersOauth' . \ucfirst($key) . 'Appid', ''))
->removeAttribute('usersOauth' . \ucfirst($key) . 'Appid');
}
if (!empty($document->getAttribute('usersOauth' . \ucfirst($key) . 'Secret'))) {
$document
->setAttribute('usersOauth2' . \ucfirst($key) . 'Secret', $document->getAttribute('usersOauth' . \ucfirst($key) . 'Secret', ''))
->removeAttribute('usersOauth' . \ucfirst($key) . 'Secret');
}
$statement->execute();
} catch (\Exception $e) {
Console::error('Failed to alter table for project: ' . $project->getId() . ' with message: ' . $e->getMessage() . '/');
}
break;
case Database::SYSTEM_COLLECTION_PROJECTS:
case Database::SYSTEM_COLLECTION_TASKS:
$document->setAttribute('security', ($document->getAttribute('security')) ? true : false);
break;
case Database::SYSTEM_COLLECTION_USERS:
foreach ($providers as $key => $provider) {
if (!empty($document->getAttribute('oauth' . \ucfirst($key)))) {
$document
->setAttribute('oauth2' . \ucfirst($key), $document->getAttribute('oauth' . \ucfirst($key), ''))
->removeAttribute('oauth' . \ucfirst($key));
}
if (!empty($document->getAttribute('oauth' . \ucfirst($key) . 'AccessToken'))) {
$document
->setAttribute('oauth2' . \ucfirst($key) . 'AccessToken', $document->getAttribute('oauth' . \ucfirst($key) . 'AccessToken', ''))
->removeAttribute('oauth' . \ucfirst($key) . 'AccessToken');
}
}
if ($document->getAttribute('confirm', null) !== null) {
$document
->setAttribute('emailVerification', $document->getAttribute('confirm', $document->getAttribute('emailVerification', false)))
->removeAttribute('confirm');
}
break;
case Database::SYSTEM_COLLECTION_PLATFORMS:
if ($document->getAttribute('url', null) !== null) {
$document
->setAttribute('hostname', \parse_url($document->getAttribute('url', $document->getAttribute('hostname', '')), PHP_URL_HOST))
->removeAttribute('url');
}
break;
}
$document
->setAttribute('$id', $document->getAttribute('$uid', $document->getAttribute('$id')))
->removeAttribute('$uid');
protected function fixDocument(Document $document)
{
$providers = Config::getParam('providers');
foreach ($document as &$attr) { // Handle child documents
if ($attr instanceof Document) {
$attr = $this->fixDocument($attr);
}
switch ($document->getAttribute('$collection')) {
case Database::SYSTEM_COLLECTION_PROJECTS:
foreach ($providers as $key => $provider) {
if (!empty($document->getAttribute('usersOauth' . \ucfirst($key) . 'Appid'))) {
$document
->setAttribute('usersOauth2' . \ucfirst($key) . 'Appid', $document->getAttribute('usersOauth' . \ucfirst($key) . 'Appid', ''))
->removeAttribute('usersOauth' . \ucfirst($key) . 'Appid');
}
if (\is_array($attr)) {
foreach ($attr as &$child) {
if ($child instanceof Document) {
$child = $this->fixDocument($child);
}
if (!empty($document->getAttribute('usersOauth' . \ucfirst($key) . 'Secret'))) {
$document
->setAttribute('usersOauth2' . \ucfirst($key) . 'Secret', $document->getAttribute('usersOauth' . \ucfirst($key) . 'Secret', ''))
->removeAttribute('usersOauth' . \ucfirst($key) . 'Secret');
}
}
break;
case Database::SYSTEM_COLLECTION_PROJECTS:
case Database::SYSTEM_COLLECTION_TASKS:
$document->setAttribute('security', ($document->getAttribute('security')) ? true : false);
break;
case Database::SYSTEM_COLLECTION_USERS:
foreach ($providers as $key => $provider) {
if (!empty($document->getAttribute('oauth' . \ucfirst($key)))) {
$document
->setAttribute('oauth2' . \ucfirst($key), $document->getAttribute('oauth' . \ucfirst($key), ''))
->removeAttribute('oauth' . \ucfirst($key));
}
if (!empty($document->getAttribute('oauth' . \ucfirst($key) . 'AccessToken'))) {
$document
->setAttribute('oauth2' . \ucfirst($key) . 'AccessToken', $document->getAttribute('oauth' . \ucfirst($key) . 'AccessToken', ''))
->removeAttribute('oauth' . \ucfirst($key) . 'AccessToken');
}
}
if ($document->getAttribute('confirm', null) !== null) {
$document
->setAttribute('emailVerification', $document->getAttribute('confirm', $document->getAttribute('emailVerification', false)))
->removeAttribute('confirm');
}
break;
case Database::SYSTEM_COLLECTION_PLATFORMS:
if ($document->getAttribute('url', null) !== null) {
$document
->setAttribute('hostname', \parse_url($document->getAttribute('url', $document->getAttribute('hostname', '')), PHP_URL_HOST))
->removeAttribute('url');
}
break;
}
}
}
return $document;
}
$document
->setAttribute('$id', $document->getAttribute('$uid', $document->getAttribute('$id')))
->removeAttribute('$uid');
foreach ($document as &$attr) { // Handle child documents
if ($attr instanceof Document) {
$attr = $this->fixDocument($attr);
}
if (\is_array($attr)) {
foreach ($attr as &$child) {
if ($child instanceof Document) {
$child = $this->fixDocument($child);
}
}
}
}
return $document;
}
}

View file

@ -3,15 +3,31 @@
namespace Appwrite\Migration\Version;
use Utopia\CLI\Console;
use Appwrite\Database\Database;
use Appwrite\Database\Document;
use Appwrite\Migration\Migration;
class V06 extends Migration
{
public function execute(): void
{
Console::log('I got nothing to do. Yet.');
public function execute(): void
{
Console::log('I got nothing to do. Yet.');
//TODO: migrate new `filter` property
//TODO: migrate new `filter` property
$this->forEachDocument([$this, 'fixDocument']);
}
}
protected function fixDocument(Document $document)
{
switch ($document->getAttribute('$collection')) {
case Database::SYSTEM_COLLECTION_USERS:
if ($document->getAttribute('password-update', null)) {
$document
->setAttribute('passwordUpdate', $document->getAttribute('password-update', $document->getAttribute('passwordUpdate', '')))
->removeAttribute('password-update');
}
break;
}
return $document;
}
}